home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume23 / trn / part09 < prev    next >
Encoding:
Text File  |  1991-08-22  |  64.3 KB  |  2,498 lines

  1. This is a new archive version of TRN at patchlevel 3.
  2. The original posting took up Volume23, issues 60 to 73, with
  3. various problems.  These files replace those issues.
  4.  
  5. #! /bin/sh
  6. # This is a shell archive.  Remove anything before this line, then feed it
  7. # into a shell via "sh file" or similar.  To overwrite existing files,
  8. # type "sh file -c".
  9. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  10. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  11. # Contents:  Pnews.SH getdate.y help.c rn.c
  12. # Wrapped by rsalz@litchi.bbn.com on Fri Aug 23 16:38:59 1991
  13. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  14. echo If this archive is complete, you will see the following message:
  15. echo '          "shar: End of archive 9 (of 14)."'
  16. if test -f 'Pnews.SH' -a "${1}" != "-c" ; then 
  17.   echo shar: Will not clobber existing file \"'Pnews.SH'\"
  18. else
  19.   echo shar: Extracting \"'Pnews.SH'\" \(18036 characters\)
  20.   sed "s/^X//" >'Pnews.SH' <<'END_OF_FILE'
  21. Xcase $CONFIG in
  22. X    '') . ./config.sh ;;
  23. Xesac
  24. Xecho "Extracting Pnews (with variable substitutions)"
  25. X$spitshell >Pnews <<!GROK!THIS!
  26. X$startsh
  27. X# $Header: Pnews.SH,v 4.3.3.3 91/01/16 03:27:15 davison Trn $
  28. X#
  29. X# $Log:    Pnews.SH,v $
  30. X# Revision 4.3.3.3  91/01/16  03:27:15  davison
  31. X# Integrated rn patches 48-54.
  32. X# 
  33. X# Revision 4.3.3.2  90/08/20  16:24:09  davison
  34. X# Use mbox.saver for AUTHORCOPY.  Fixed sitename handling.
  35. X# 
  36. X# Revision 4.3.3.1  90/07/24  22:01:25  davison
  37. X# Initial Trn Release
  38. X# 
  39. X# Revision 4.3.2.14  91/01/05  15:18:19  sob
  40. X# Changed the header purge code to use sed instead of grep.
  41. X# 
  42. X# Revision 4.3.2.13  90/12/30  03:47:57  sob
  43. X# Changed "hidden" to "hiddennet" to be like nntp and bnews.
  44. X# Made it possible to cancel articles if hiddennet is defined.
  45. X# 
  46. X# Revision 4.3.2.12  90/12/30  03:27:44  sob
  47. X# Corrected a spelling problem.
  48. X# 
  49. X# Revision 4.3.2.11  90/12/04  02:47:54  sob
  50. X# Added a fix to remove blank lines in the header before posting.
  51. X# 
  52. X# Revision 4.3.2.10  90/11/22  13:45:40  sob
  53. X# Added support for making news posting appear to come from the domain
  54. X# itself instead of individual hosts withing a domain.
  55. X# 
  56. X# Revision 4.3.2.9  90/11/06  00:54:52  sob
  57. X# Added ./ to be beginning of config.sh
  58. X# 
  59. X# Revision 4.3.2.8  90/11/06  00:08:11  sob
  60. X# Fixed bug in sed syntax for usg password file format per bug report by
  61. X# prc@erbe.se
  62. X# 
  63. X# Revision 4.3.2.7  90/05/04  23:14:45  sob
  64. X# Expires: line removed from Pnews.header.
  65. X# 
  66. X# Revision 4.3.2.6  90/04/21  16:53:43  sob
  67. X# Corrected a typo pointed out by Bill Aten.
  68. X# 
  69. X# Revision 4.3.2.5  89/12/17  01:53:48  sob
  70. X# Changed from using ypcat to using ypmatch
  71. X# 
  72. X# Revision 4.3.2.4  89/12/09  01:48:30  sob
  73. X# Reply-To: field removed. This makes all the headers created by rn
  74. X# look roughly the same.
  75. X# 
  76. X# Revision 4.3.2.3  89/11/26  22:20:04  sob
  77. X# Added support for some of the top level names that are not part of
  78. X# the mainstream.
  79. X# 
  80. X# Revision 4.3.2.2  89/11/06  00:25:39  sob
  81. X# Some minor changes to make the help messages more accurate
  82. X# 
  83. X# Revision 4.3.2.1  89/11/06  00:21:30  sob
  84. X# Added RRN support from NNTP 1.5
  85. X# 
  86. X# Revision 4.3.1.4  86/09/05  15:21:10  lwall
  87. X# Changes for new top-level newsgroup names.
  88. X# 
  89. X# Revision 4.3.1.3  85/08/01  14:24:06  lwall
  90. X# Added AUTHORCOPY.  Temp file is no longer in /tmp.  'e editor' added.
  91. X# 
  92. X# Revision 4.3.1.2  85/05/17  10:36:46  lwall
  93. X# Removed some extra backslashes.
  94. X# 
  95. X# Revision 4.3.1.1  85/05/10  11:30:21  lwall
  96. X# Branch for patches.
  97. X# 
  98. X# Revision 4.3  85/05/01  12:20:33  lwall
  99. X# Baseline for release with 4.3bsd.
  100. X# 
  101. X#
  102. X# syntax: Pnews -h headerfile            or
  103. X#      Pnews -h headerfile oldarticle    or
  104. X#         Pnews newsgroup title            or just
  105. X#         Pnews
  106. X
  107. Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
  108. X
  109. X# System dependencies
  110. X
  111. Xmailer="${mailer-/bin/mail}"
  112. X# if you change this to something that does signatures, take out signature code
  113. X
  114. Xcase $portable in
  115. Xdefine)
  116. X# your site name
  117. Xcase "$hostcmd" in
  118. X'') sitename="$sitename" ;;
  119. X*)  sitename=\`$hostcmd\` ;;
  120. Xesac
  121. Xcase \$sitename in
  122. X    *.*)
  123. X        ;;
  124. X    *)
  125. X        sitename=\${sitename}.$domain
  126. X        ;;
  127. Xesac
  128. X# where recordings, distributions and moderators are kept
  129. Xlib=\`$filexp $lib\`
  130. X# where important rn things are kept
  131. Xrnlib=\`$filexp $rnlib\`
  132. X;;
  133. Xundef)
  134. X# your site name
  135. Xsitename="$sitename"
  136. X# where recordings, distributions and moderators are kept
  137. Xlib="$lib"
  138. X# where important rn things are kept
  139. Xrnlib="$rnlib"
  140. X;;
  141. Xesac
  142. X
  143. Xcase $hiddennet in
  144. Xdefine)    sitename="$domain"
  145. X    ;;
  146. X*)
  147. X    ;;
  148. Xesac
  149. X
  150. X# your organization name
  151. Xorgname="$orgname"
  152. X# what pager you use--if you have kernal paging use cat
  153. Xpager="\${PAGER-$pager}"
  154. X# how you derive full names, bsd, usg, or other
  155. Xnametype="$nametype"
  156. X# default editor
  157. Xdefeditor="$defeditor"
  158. X# how not to echo with newline
  159. Xn="$n"
  160. Xc="$c"
  161. X
  162. X# You should also look at the distribution warnings below marked !DIST!
  163. X# to make sure any distribution regions you are a member of are included.
  164. X# The following are some prototypical distribution groups.  If you do not
  165. X# use them all set the unused ones to a non-null string such as 'none'.
  166. Xloc="$locpref"
  167. Xorg="$orgpref"
  168. Xcity="$citypref"
  169. Xstate="$statepref"
  170. Xcntry="$cntrypref"
  171. Xcont="$contpref"
  172. X
  173. Xtest=${test-test}
  174. Xsed=${sed-sed}
  175. Xecho=${echo-echo}
  176. Xcat=${cat-cat}
  177. Xegrep=${egrep-egrep}
  178. Xgrep=${grep-grep}
  179. Xrm=${rm-rm}
  180. Xtr=${tr-tr}
  181. Xinews=${inews-inews}
  182. Xnidump=${nidump}
  183. Xypmatch=${ypmatch}
  184. X
  185. X!GROK!THIS!
  186. X$spitshell >>Pnews <<'!NO!SUBS!'
  187. Xdotdir=${DOTDIR-${HOME-$LOGDIR}}
  188. Xtmpart=$dotdir/.article
  189. X
  190. Xif $test -f $dotdir/.pnewsexpert; then
  191. X    expertise=expert
  192. Xelse
  193. X    $cat <<'EOM'
  194. XI see you've never used this version of Pnews before.  I will give you extra
  195. Xhelp this first time through, but then you must remember what you learned.
  196. XIf you don't understand any question, type h and a CR (carriage return) for
  197. Xhelp.
  198. X
  199. XIf you've never posted an article to the net before, it is HIGHLY recommended
  200. Xthat you read the netiquette document found in news.announce.newusers so
  201. Xthat you'll know to avoid the commonest blunders.  To do that, interrupt
  202. XPnews, and get to the top-level prompt of rn.  Type "g news.announce.newusers"
  203. Xand you are on your way.
  204. X
  205. XEOM
  206. X    expertise=beginner
  207. Xfi
  208. X
  209. Xcase $cntry in
  210. X  can) stpr=Province ;;
  211. X  *)   stpr=State ;;
  212. Xesac
  213. X
  214. Xheaderfile=""
  215. Xcase $# in
  216. X0) ;;
  217. X*)  case $1 in
  218. X    -h)
  219. X    headerfile="$2"
  220. X    shift
  221. X    shift
  222. X    case $# in
  223. X    0)
  224. X        oldart=""
  225. X        ;;
  226. X    *)
  227. X        oldart="$1"
  228. X        shift
  229. X        ;;
  230. X    esac
  231. X    ;;
  232. X    esac
  233. X    ;;
  234. Xesac
  235. X
  236. Xcase $headerfile in
  237. X'')
  238. X    . $rnlib/Pnews.header
  239. X    ;;
  240. X*)
  241. X    $cat < $headerfile  > $tmpart
  242. X    ;;
  243. Xesac
  244. X    rescue="sleep 1; $cat $tmpart >>${HOME-$LOGDIR}/dead.article ; $echo Article appended to ${HOME-$LOGDIR}/dead.article ; exit"
  245. X    trap "$rescue" 1
  246. X    trap "$rescue" 2
  247. X
  248. X$echo ""
  249. X
  250. X# extract the newsgroups list and distribution
  251. Xhdr_newsgroups=`$sed -n -e '/^Newsgroups:/{' -e 's///' -e 's/,/ /g' -e p -e q -e '}' $tmpart`
  252. Xhdr_distribution=`$sed -n -e '/^Distribution:/{' -e 's///' -e p -e q -e '}' $tmpart`
  253. X
  254. X# check for "poster" magic cookie
  255. Xflag=0
  256. Xfor ng in $hdr_newsgroups ; do
  257. X    case "$ng" in
  258. X    poster)    flag=1 ;;
  259. X    *)    ;;
  260. X    esac
  261. Xdone
  262. Xcase $flag in
  263. X1)
  264. X    $echo " "
  265. X    $echo "The original author has requested that messages be sent back via"
  266. X    $echo "mail rather than posting to news.  Do you want to jump out of this"
  267. X    $echo $n "and mail your reply instead? [yn] $c"
  268. X    read ans
  269. X    case $ans in
  270. X    n*) ;;
  271. X    *)  exit ;;
  272. X    esac
  273. X    $echo " "
  274. X    $echo "OK, but you will have to edit the 'Newsgroups:' line in the message."
  275. X    ;;
  276. Xesac
  277. X  
  278. X# play recorded message
  279. Xif $test -s ${lib}/recording ; then
  280. X     for ng in $hdr_newsgroups ; do
  281. X    _rec1=${lib}/`$sed -n "/^$ng/s/^.*    //p" ${lib}/recording`
  282. X    _tmp=`$echo $ng |$sed "s/\..*//"`
  283. X    _rec2=${lib}/`$cat -s ${lib}/recording|$grep ${_tmp}.all|$sed "s/^.*    //"`
  284. X    if $test -f ${_rec1} ; then
  285. X        $cat -s ${_rec1}
  286. X    fi
  287. X    if $test -f ${_rec2} ; then
  288. X        $cat -s ${_rec2}
  289. X    fi
  290. X    done
  291. Xfi
  292. X
  293. X# determine the distribution of this message
  294. Xset X $hdr_distribution
  295. Xshift
  296. Xif $test $# -gt 0 ; then
  297. X    dist=$1.whatever
  298. Xelse
  299. X    set X $hdr_newsgroups
  300. X    shift
  301. X    if $test $# -gt 0 ; then
  302. X    dist=$1.whatever
  303. X    else
  304. X    dist=misc.whatever
  305. X    fi
  306. Xfi
  307. Xcase $dist in
  308. X*.*)
  309. X    ;;
  310. X*)
  311. X    dist=$dist.whatever
  312. X    ;;
  313. Xesac
  314. X
  315. X# tell them what we think they are doing... !DIST!
  316. Xcase $dist in
  317. Xworld.*|comp.*|news.*|sci.*|rec.*|misc.*|soc.*|talk.*|alt.*)
  318. X    $cat <<'EOM'
  319. XThis program posts news to thousands of machines throughout the entire
  320. Xcivilized world.  Your message will cost the net hundreds if not thousands of
  321. Xdollars to send everywhere.  Please be sure you know what you are doing.
  322. X
  323. XEOM
  324. X    ;;
  325. Xvmsnet.*)
  326. X    $echo 'This program posts news to many machines.'
  327. X    ;;
  328. Xbit.*)
  329. X    $echo 'This program posts news to many machines on BITNET.'
  330. X    ;;
  331. Xddn.*)
  332. X    $echo 'This program posts news to many machines throughout the internet.'
  333. X    ;;
  334. X$cont.*)
  335. X    $echo 'This program posts news to many machines throughout the continent.'
  336. X    ;;
  337. X$cntry.*)
  338. X    $echo 'This program posts news to many machines throughout the country.'
  339. X    ;;
  340. X$state.*)
  341. X    $echo 'This program posts news to many machines throughout the state.'
  342. X    ;;
  343. X$city.*)
  344. X    $echo 'This program posts news to many machines throughout the city.'
  345. X    ;;
  346. X$org.*)
  347. X    $echo 'This program posts news to machines throughout the organization.'
  348. X    ;;
  349. X$loc.*)
  350. X    $echo 'This program posts news to machines throughout the local organization.'
  351. X    ;;
  352. X*.*)
  353. X    $echo 'This program may post news to many machines.'
  354. X    ;;
  355. Xto.*)
  356. X    $echo 'This program may post news to a particular machine.'
  357. X    ;;
  358. X*)
  359. X    $echo 'This program posts news to everyone on the machine.'
  360. X    ;;
  361. Xesac
  362. Xans=""
  363. Xwhile $test "$ans" = "" ; do
  364. X    $echo $n "Are you absolutely sure that you want to do this? [ny] $c"
  365. X    read ans
  366. X    case $ans in
  367. X    y*) ;;
  368. X    f*) ;;
  369. X    h*) $cat <<'EOH'
  370. X
  371. XType n or CR to exit, y to post.
  372. X
  373. XEOH
  374. X    ans="" ;;
  375. X    *) exit ;;
  376. X    esac
  377. Xdone
  378. X
  379. Xfile=h
  380. Xwhile $test "$file" = h ; do
  381. X    $echo ""
  382. X    $echo $n "Prepared file to include [none]: $c"
  383. X    read file
  384. X    case $file in
  385. X    h)
  386. X    $cat <<'EOH'
  387. X
  388. XIf you have already produced the body of your article, type the filename
  389. Xfor it here.  If you just want to proceed directly to the editor, type a
  390. XRETURN.  In any event, you will be allowed to edit as many times as you
  391. Xwant before you send off the article.
  392. XEOH
  393. X    ;;
  394. X    '')
  395. X    $echo "" >> $tmpart
  396. X    state=edit
  397. X    ;;
  398. X    *)
  399. X    $cat $file >>$tmpart
  400. X    state=ask
  401. X    ;;
  402. X    esac
  403. Xdone
  404. X
  405. X$echo ""
  406. X
  407. Xwhile true ; do
  408. X    case $state in
  409. X    edit)
  410. X    case $expertise in
  411. X    beginner)
  412. X        $cat </dev/null >$dotdir/.pnewsexpert
  413. X        $cat <<'EOMessage'
  414. XA temporary file has been created for you to edit.  Be sure to leave at
  415. Xleast one blank line between the header and the body of your message.
  416. X(And until a certain bug is fixed all over the net, don't start the body of
  417. Xyour message with any indentation, or it may get eaten.)
  418. X
  419. XWithin the header may be fields that you don't understand.  If you don't
  420. Xunderstand a field (or even if you do), you can simply leave it blank, and
  421. Xit will go away when the article is posted.
  422. X
  423. XType return to get the default editor, or type the name of your favorite
  424. Xeditor.
  425. X
  426. XEOMessage
  427. X        ;;
  428. X    esac
  429. X    case "${VISUAL-${EDITOR-}}" in
  430. X    '')
  431. X        tmp=h
  432. X        ;;
  433. X    *)
  434. X        tmp=''
  435. X        ;;
  436. X    esac
  437. X    while $test "$tmp" = h ; do
  438. X        $echo $n "Editor [${VISUAL-${EDITOR-$defeditor}}]: $c"
  439. X        read tmp
  440. X        case $tmp in
  441. X        h)
  442. X        $cat <<'EOH'
  443. X
  444. XType a return to get the default editor, or type the name of the editor you
  445. Xprefer.  The default editor depends on the VISUAL and EDITOR environment
  446. Xvariables.
  447. X
  448. XEOH
  449. X        ;;
  450. X        '')
  451. X        ;;
  452. X        *)
  453. X        VISUAL=$tmp
  454. X        export VISUAL
  455. X        ;;
  456. X        esac
  457. X    done
  458. X    trap : 2
  459. X    ${VISUAL-${EDITOR-$defeditor}} $tmpart $oldart
  460. X    trap "$rescue" 2
  461. X    state=ask
  462. X    ;;
  463. X    
  464. X    ask)
  465. X    $echo ""
  466. X    $echo $n "Send, abort, edit, or list? $c"
  467. X    read ans
  468. X    
  469. X    case "$ans" in
  470. X    a*)
  471. X        state=rescue
  472. X        ;;
  473. X    e*)
  474. X        set $ans
  475. X        case $# in
  476. X        2)  VISUAL="$2" ;;
  477. X        esac
  478. X        state=edit
  479. X        ;;
  480. X    l*)
  481. X        $pager $tmpart
  482. X        state=ask
  483. X        ;;
  484. X    s*)
  485. X        state=send
  486. X        ;;
  487. X    h*)
  488. X        $cat <<'EOH'
  489. X
  490. XType s to send the article, a to abort and append the article to dead.article,
  491. Xe to edit the article again, or l to list the article.
  492. X
  493. XTo invoke an alternate editor, type 'e editor'.
  494. XEOH
  495. X    esac
  496. X    ;;
  497. X    
  498. X    send)
  499. X    set X `$sed < $tmpart -n -e '/^Newsgroups: /{' -e p -e q -e '}'`
  500. X    shift
  501. X    case $# in
  502. X    2)
  503. X        state=cleanup
  504. X        if $test -f $lib/moderators; then
  505. X        tryinews=no
  506. X        shift
  507. X        case "$1" in
  508. X        *,*) set `$echo $1 | tr ',' ' '`;;
  509. X        esac
  510. X        for newsgroup in $*; do
  511. X# the following screwy sed should prevent Eunice from hanging on no match
  512. X            moderator=`$sed <$lib/moderators \
  513. X            -e "/^$newsgroup[     ]/!s/.*//" \
  514. X            -e "s/^$newsgroup[     ]//"`
  515. X            case ${moderator}X in
  516. X            X)  tryinews=yes
  517. X            ;;
  518. X            *)
  519. X            $echo Mailing to moderator $moderator
  520. X            case "$sign" in
  521. X            n*) ;;
  522. X            *)
  523. X                if $test -f $dotdir/.signature; then
  524. X                echo $n "Append .signature file? [y] $c"
  525. X                read ans
  526. X                case $ans in
  527. X                ''|y*)
  528. X                    echo "-- " >> $tmpart
  529. X                    cat $dotdir/.signature >> $tmpart
  530. X                    ;;
  531. X                esac
  532. X                fi
  533. X                sign=no
  534. X                ;;
  535. X            esac
  536. X            case "$mailer" in
  537. X            *recmail)
  538. X                $echo To: $moderator | $cat - $tmpart | $mailer
  539. X                ;;
  540. X            *)
  541. X                $mailer $moderator < $tmpart
  542. X                ;;
  543. X            esac
  544. X            case $? in
  545. X            0) ;;
  546. X            *)
  547. X                $echo Unable to mail to moderator $moderator
  548. X                state=rescue
  549. X                ;;
  550. X            esac
  551. X            ;;
  552. X            esac
  553. X        done
  554. X        else
  555. X        tryinews=yes
  556. X        fi
  557. X        case "$tryinews" in
  558. X        yes)
  559. X        if $sed '1,/^[     ]*$/{/^[A-Z][-A-Za-z0-9]*:[     ]*$/d;}' $tmpart |
  560. X            $inews -h ; then
  561. X            : null
  562. X        else
  563. X            state=rescue
  564. X        fi
  565. X        ;;
  566. X        esac
  567. X        ;;
  568. X    *)
  569. X        $echo ""
  570. X        $echo "Malformed Newsgroups line."
  571. X        $echo ""
  572. X        sleep 1
  573. X        state=edit
  574. X        ;;
  575. X    esac
  576. X    ;;
  577. X    rescue)
  578. X    if $test -s $tmpart; then
  579. X        $cat $tmpart >> ${HOME-$LOGDIR}/dead.article
  580. X        $echo "Article appended to ${HOME-$LOGDIR}/dead.article"
  581. X        $echo "A copy may be temporarily found in $tmpart"
  582. X    else
  583. X        $echo "Null article discarded."
  584. X    fi
  585. X    exit
  586. X    ;;
  587. X    cleanup)
  588. X    case "${AUTHORCOPY-none}" in
  589. X    none)
  590. X        ;;
  591. X    *)
  592. X        set X ${USER-${LOGNAME-`who am i`}} unknown
  593. X        shift
  594. X        $rnlib/mbox.saver $tmpart "." "." 0 0 Pnews $AUTHORCOPY "From $1 `date`"
  595. X        if $test $? -eq 0 ; then
  596. X        $echo "Article appended to $AUTHORCOPY"
  597. X        else
  598. X        $echo "Cannot append to $AUTHORCOPY"
  599. X        fi
  600. X        ;;
  601. X    esac
  602. X    exit
  603. X    ;;
  604. X    esac
  605. Xdone
  606. X!NO!SUBS!
  607. X$eunicefix Pnews
  608. Xchmod 755 Pnews
  609. X$spitshell >Pnews.header <<'!NO!SUBS!'
  610. Xcase $# in
  611. X0)
  612. X    ng=h
  613. X    while $test "$ng" = h ; do
  614. X    $echo ""
  615. X    $echo $n "Newsgroup(s): $c"
  616. X    read ng
  617. X    case $ng in
  618. X    h)
  619. X        $cat <<'EOH'
  620. X
  621. XType the name of one or more newsgroups to which you wish to post an article.
  622. XIf you want to post to multiple newsgroups, it is better to do them all at
  623. Xonce than to post to each newsgroup individually, which defeats the news
  624. Xreading programs' strategies of eliminating duplicates.
  625. X
  626. XSeparate multiple newsgroup names with commas.
  627. XEOH
  628. X        ;;
  629. X    esac
  630. X    done
  631. X    ;;
  632. X*)
  633. X    ng=$1
  634. X    shift
  635. X    ;;
  636. Xesac
  637. Xcase $ng in
  638. X*\ *)
  639. X    ng=`$echo "$ng" | $sed 's/[, ] */,/g'`
  640. X    ;;
  641. Xesac
  642. Xcase $ng in
  643. Xbit.*|pubnet.*|bionet.*|vmsnet.*|comp.*|news.*|sci.*|rec.*|misc.*|soc.*|talk.*|alt.*)
  644. X    defdist=world
  645. X    dist=h
  646. X    ;;
  647. Xddn.*)
  648. X    defdist=inet
  649. X    dist=h
  650. X    ;;
  651. Xto.*)
  652. X    defdist=''
  653. X    dist=''
  654. X    ;;
  655. X*.*)
  656. X    defdist=`expr "X$ng" : 'X\([a-z0-9]*\)'`
  657. X    dist=h
  658. X    ;;
  659. X*)
  660. X    defdist=''
  661. X    dist=''
  662. X    ;;
  663. Xesac
  664. X
  665. Xwhile $test "$dist" = h ; do
  666. X    if $test -f $lib/distributions; then
  667. X    $echo " "
  668. X    $echo "Your local distribution prefixes are:"
  669. X    $cat $lib/distributions
  670. X    $echo " "
  671. X    else
  672. X    $egrep -v '[     ]none$' <<EOM
  673. X
  674. XYour local distribution prefixes are:
  675. X    Local organization:    $loc
  676. X    Organization:    $org
  677. X    City:        $city
  678. X    $stpr:          $state
  679. X    Country:        $cntry
  680. X    Continent:        $cont
  681. X    Everywhere:        world
  682. X
  683. XEOM
  684. X    fi
  685. X    $echo $n "Distribution ($defdist): $c"
  686. X    read dist
  687. X    case $dist in
  688. X    '') dist=$defdist ;;
  689. X    esac
  690. X    case $dist in
  691. X    h)
  692. X    $cat <<'EOH'
  693. X
  694. XThe Distribution line may be used to limit the distribution of an article
  695. Xto some subset of the systems that would receive the article based only on
  696. Xthe Newsgroups line.  For example, if you want to sell your car in talk.auto,
  697. Xand you live in New Jersey, you might want to put "nj" on the Distribution
  698. Xline to avoid advertising in California, which has enough problems of its own.
  699. XThe actual area designators to use depend on where you are, of course.
  700. XEOH
  701. X    ;;
  702. X    ''|$loc*|$org*|$city*|$state*|$cntry*|$cont*|$defdist)
  703. X    ;;
  704. X    world*|comp*|news*|sci*|rec*|misc*|soc*|talk*|alt*)
  705. X    dist=''
  706. X    ;;
  707. X    *)  
  708. X    if $test -f $lib/distributions && \
  709. X      $egrep "^$dist[     ]" $lib/distributions >$tmpart && \
  710. X      $test -s $tmpart; then
  711. X        : null
  712. X    else
  713. X        $echo "Unrecognized distribution prefix--type h for help, CR to use anyway."
  714. X        defdist=$dist
  715. X        dist=h
  716. X    fi
  717. X    ;;
  718. X    esac
  719. Xdone
  720. X
  721. Xfollow=""
  722. X
  723. Xcase $# in
  724. X0)
  725. X    title=h
  726. X    while $test "$title" = h ; do
  727. X    $echo ""
  728. X    $echo $n "Title/Subject: $c"
  729. X    read title
  730. X    case $title in
  731. X    h)
  732. X        $cat <<'EOH'
  733. X
  734. XType the title for your article.  Please make it as informative as possible
  735. X(within reason) so that people who aren't interested won't have to read the
  736. Xarticle to find out they aren't interested.  This includes marking movie
  737. Xspoilers as (spoiler), and rotated jokes as (rot 13).
  738. XEOH
  739. X    ;;
  740. X    esac
  741. X    done
  742. X    ;;
  743. X*)
  744. X    title="$*"
  745. X    ;;
  746. Xesac
  747. X
  748. X# now build a file with a header for them to edit
  749. X
  750. Xset X ${USER-${LOGNAME-`who am i`}}
  751. Xshift
  752. Xlogname=$1
  753. Xcase $logname in
  754. X*!*) logname=`expr "$logname" : '!\(.*\)$'` ;;
  755. Xesac
  756. Xcase ${NAME-$nametype} in
  757. Xbsd)
  758. X    if $test "$ypmatch" != ""; then
  759. X        fullname=`$ypmatch $logname passwd 2>/dev/null | $sed "s/^[^:]*:[^:]*:[^:]*:[^:]*:\([^,:;]*\).*"'$'"/\1/"`
  760. X    elif $test "$nidump" != ""; then
  761. X        fullname=`$nidump passwd / | $sed -e "/^$logname:/{s/^[^:]*:[^:]*:[^:]*:[^:]*:\([^,:;]*\).*"'$'"/\1/" -e "q" -e "}" -e "d"`
  762. X    fi
  763. X     if $test "$fullname" = ""; then
  764. X        fullname=`$sed </etc/passwd -e "/^$logname:/{s/^[^:]*:[^:]*:[^:]*:[^:]*:\([^,:;]*\).*"'$'"/\1/" -e "q" -e "}" -e "d"`
  765. X    fi
  766. X    case $fullname in
  767. X    *'&'*) : GACK
  768. X    lname=`$echo $logname | $tr 'a-z' 'A-Z'`
  769. X    lname=`$echo $lname $logname | $sed 's/^\(.\)[^ ]* ./\1/'`
  770. X    fullname=`$echo "$fullname" | $sed "s/&/${lname}/"`
  771. X    ;;
  772. X    esac
  773. X    ;;
  774. Xusg)
  775. X    if $test "$ypmatch" != ""; then
  776. X        fullname=`$ypmatch $logname passwd 2>/dev/null | $sed -e "s/^[^:]*:[^:]*:[^:]*:[^:]*:\([^(:]*\).*"'$'"/\1/" -e "s/^.*-//" -e "q"`
  777. X    fi
  778. X     if $test "$fullname" = ""; then
  779. X    fullname=`$sed </etc/passwd -e "/^$logname:/{s/^[^:]*:[^:]*:[^:]*:[^:]*:\([^(:]*\).*"'$'"/\1/" -e "s/^.*-//" -e "q" -e "}" -e "d"`
  780. X    fi
  781. X    ;;
  782. X*)
  783. X    fullname=${NAME-`$cat $dotdir/.fullname`}
  784. X    ;;
  785. Xesac
  786. X
  787. Xorgname=${ORGANIZATION-$orgname}
  788. Xcase $orgname in
  789. X/*) orgname=`$cat $orgname` ;;
  790. Xesac
  791. X
  792. X$sed -e '/^Reply-To: $/d' > $tmpart <<EOHeader
  793. XNewsgroups: $ng
  794. XSubject: $title
  795. XSummary: 
  796. XReply-To: $REPLYTO
  797. XFollowup-To: $follow
  798. XDistribution: $dist
  799. XOrganization: $orgname
  800. XKeywords: 
  801. X
  802. XEOHeader
  803. X
  804. X!NO!SUBS!
  805. Xcase "$isrrn" in
  806. Xdefine) sed < Pnews.header -e '/^#NORMAL/d' > Pnews.h.new ;;
  807. X*)  sed < Pnews.header -e '/^#NORMAL/s/^#NORMAL//' > Pnews.h.new ;;
  808. Xesac
  809. Xmv Pnews.h.new Pnews.header
  810. X$eunicefix Pnews.header
  811. END_OF_FILE
  812.   if test 18036 -ne `wc -c <'Pnews.SH'`; then
  813.     echo shar: \"'Pnews.SH'\" unpacked with wrong size!
  814.   fi
  815.   chmod +x 'Pnews.SH'
  816.   # end of 'Pnews.SH'
  817. fi
  818. if test -f 'getdate.y' -a "${1}" != "-c" ; then 
  819.   echo shar: Will not clobber existing file \"'getdate.y'\"
  820. else
  821.   echo shar: Extracting \"'getdate.y'\" \(12373 characters\)
  822.   sed "s/^X//" >'getdate.y' <<'END_OF_FILE'
  823. X%token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO
  824. X%{
  825. X    /*     Steven M. Bellovin (unc!smb)            */
  826. X    /*    Dept. of Computer Science            */
  827. X    /*    University of North Carolina at Chapel Hill    */
  828. X    /*    @(#)getdate.y    2.13    9/16/86 */
  829. X
  830. X#include <sys/types.h>
  831. X#include <ctype.h>
  832. X#include <time.h>
  833. X
  834. X#define    NULL    0
  835. X
  836. X#define daysec (24L*60L*60L)
  837. X
  838. X    static int timeflag, zoneflag, dateflag, dayflag, relflag;
  839. X    static time_t relsec, relmonth;
  840. X    static int hh, mm, ss, merid, daylight;
  841. X    static int dayord, dayreq;
  842. X    static int month, day, year;
  843. X    static int ourzone;
  844. X
  845. X#define AM 1
  846. X#define PM 2
  847. X#define DAYLIGHT 1
  848. X#define STANDARD 2
  849. X#define MAYBE    3
  850. X%}
  851. X
  852. X%%
  853. Xtimedate:         /* empty */
  854. X    | timedate item;
  855. X
  856. Xitem:    tspec =
  857. X        {timeflag++;}
  858. X    | zone =
  859. X        {zoneflag++;}
  860. X    | dtspec =
  861. X        {dateflag++;}
  862. X    | dyspec =
  863. X        {dayflag++;}
  864. X    | rspec =
  865. X        {relflag++;}
  866. X    | nspec;
  867. X
  868. Xnspec:    NUMBER =
  869. X        {if (timeflag && dateflag && !relflag) year = $1;
  870. X        else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}};
  871. X
  872. Xtspec:    NUMBER MERIDIAN =
  873. X        {hh = $1; mm = 0; ss = 0; merid = $2;}
  874. X    | NUMBER ':' NUMBER =
  875. X        {hh = $1; mm = $3; merid = 24;}
  876. X    | NUMBER ':' NUMBER MERIDIAN =
  877. X        {hh = $1; mm = $3; merid = $4;}
  878. X    | NUMBER ':' NUMBER NUMBER =
  879. X        {hh = $1; mm = $3; merid = 24;
  880. X        daylight = STANDARD; ourzone = -($4%100 + 60*$4/100);}
  881. X    | NUMBER ':' NUMBER ':' NUMBER =
  882. X        {hh = $1; mm = $3; ss = $5; merid = 24;}
  883. X    | NUMBER ':' NUMBER ':' NUMBER MERIDIAN =
  884. X        {hh = $1; mm = $3; ss = $5; merid = $6;}
  885. X    | NUMBER ':' NUMBER ':' NUMBER NUMBER =
  886. X        {hh = $1; mm = $3; ss = $5; merid = 24;
  887. X        daylight = STANDARD; ourzone = -($6%100 + 60*$6/100);};
  888. X
  889. Xzone:    ZONE =
  890. X        {ourzone = $1; daylight = STANDARD;}
  891. X    | DAYZONE =
  892. X        {ourzone = $1; daylight = DAYLIGHT;};
  893. X
  894. Xdyspec:    DAY =
  895. X        {dayord = 1; dayreq = $1;}
  896. X    | DAY ',' =
  897. X        {dayord = 1; dayreq = $1;}
  898. X    | NUMBER DAY =
  899. X        {dayord = $1; dayreq = $2;};
  900. X
  901. Xdtspec:    NUMBER '/' NUMBER =
  902. X        {month = $1; day = $3;}
  903. X    | NUMBER '/' NUMBER '/' NUMBER =
  904. X        {month = $1; day = $3; year = $5;}
  905. X    | MONTH NUMBER =
  906. X        {month = $1; day = $2;}
  907. X    | MONTH NUMBER ',' NUMBER =
  908. X        {month = $1; day = $2; year = $4;}
  909. X    | NUMBER MONTH =
  910. X        {month = $2; day = $1;}
  911. X    | NUMBER MONTH NUMBER =
  912. X        {month = $2; day = $1; year = $3;};
  913. X
  914. X
  915. Xrspec:    NUMBER UNIT =
  916. X        {relsec +=  60L * $1 * $2;}
  917. X    | NUMBER MUNIT =
  918. X        {relmonth += $1 * $2;}
  919. X    | NUMBER SUNIT =
  920. X        {relsec += $1;}
  921. X    | UNIT =
  922. X        {relsec +=  60L * $1;}
  923. X    | MUNIT =
  924. X        {relmonth += $1;}
  925. X    | SUNIT =
  926. X        {relsec++;}
  927. X    | rspec AGO =
  928. X        {relsec = -relsec; relmonth = -relmonth;};
  929. X%%
  930. X
  931. Xstatic int mdays[12] =
  932. X    {31, 0, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31};
  933. X#define epoch 1970
  934. X
  935. Xextern struct tm *localtime();
  936. Xtime_t dateconv(mm, dd, yy, h, m, s, mer, zone, dayflag)
  937. Xint mm, dd, yy, h, m, s, mer, zone, dayflag;
  938. X{
  939. X    time_t tod, jdate;
  940. X    register int i;
  941. X    time_t timeconv();
  942. X
  943. X    if (yy < 0) yy = -yy;
  944. X    if (yy < 100) yy += 1900;
  945. X    mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
  946. X    if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
  947. X        dd < 1 || dd > mdays[--mm]) return (-1);
  948. X    jdate = dd-1;
  949. X        for (i=0; i<mm; i++) jdate += mdays[i];
  950. X    for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
  951. X    jdate *= daysec;
  952. X    jdate += zone * 60L;
  953. X    if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
  954. X    jdate += tod;
  955. X    if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst))
  956. X        jdate += -1*60*60;
  957. X    return (jdate);
  958. X}
  959. X
  960. Xtime_t dayconv(ord, day, now) int ord, day; time_t now;
  961. X{
  962. X    register struct tm *loctime;
  963. X    time_t tod;
  964. X    time_t daylcorr();
  965. X
  966. X    tod = now;
  967. X    loctime = localtime(&tod);
  968. X    tod += daysec * ((day - loctime->tm_wday + 7) % 7);
  969. X    tod += 7*daysec*(ord<=0?ord:ord-1);
  970. X    return daylcorr(tod, now);
  971. X}
  972. X
  973. Xtime_t timeconv(hh, mm, ss, mer) register int hh, mm, ss, mer;
  974. X{
  975. X    if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
  976. X    switch (mer) {
  977. X        case AM: if (hh < 1 || hh > 12) return(-1);
  978. X             return (60L * ((hh%12)*60L + mm)+ss);
  979. X        case PM: if (hh < 1 || hh > 12) return(-1);
  980. X             return (60L * ((hh%12 +12)*60L + mm)+ss);
  981. X        case 24: if (hh < 0 || hh > 23) return (-1);
  982. X             return (60L * (hh*60L + mm)+ss);
  983. X        default: return (-1);
  984. X    }
  985. X}
  986. Xtime_t monthadd(sdate, relmonth) time_t sdate, relmonth;
  987. X{
  988. X    struct tm *ltime;
  989. X    time_t dateconv();
  990. X    time_t daylcorr();
  991. X    int mm, yy;
  992. X
  993. X    if (relmonth == 0) return 0;
  994. X    ltime = localtime(&sdate);
  995. X    mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
  996. X    yy = mm/12;
  997. X    mm = mm%12 + 1;
  998. X    return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
  999. X        ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
  1000. X}
  1001. X
  1002. Xtime_t daylcorr(future, now) time_t future, now;
  1003. X{
  1004. X    int fdayl, nowdayl;
  1005. X
  1006. X    nowdayl = (localtime(&now)->tm_hour+1) % 24;
  1007. X    fdayl = (localtime(&future)->tm_hour+1) % 24;
  1008. X    return (future-now) + 60L*60L*(nowdayl-fdayl);
  1009. X}
  1010. X
  1011. Xstatic char *lptr;
  1012. X
  1013. Xyylex()
  1014. X{
  1015. X    extern int yylval;
  1016. X    int sign;
  1017. X    register char c;
  1018. X    register char *p;
  1019. X    char idbuf[20];
  1020. X    int pcnt;
  1021. X
  1022. X    for (;;) {
  1023. X        while (isspace(*lptr)) lptr++;
  1024. X
  1025. X        if (isdigit(c = *lptr) || c == '-' || c == '+') {
  1026. X            if (c== '-' || c == '+') {
  1027. X                if (c=='-') sign = -1;
  1028. X                else sign = 1;
  1029. X                if (!isdigit(*++lptr)) {
  1030. X                    /* yylval = sign; return (NUMBER); */
  1031. X                    return yylex();    /* skip the '-' sign */
  1032. X                }
  1033. X            } else sign = 1;
  1034. X            yylval = 0;
  1035. X            while (isdigit(c = *lptr++)) yylval = 10*yylval + c - '0';
  1036. X            yylval *= sign;
  1037. X            lptr--;
  1038. X            return (NUMBER);
  1039. X
  1040. X        } else if (isalpha(c)) {
  1041. X            p = idbuf;
  1042. X            while (isalpha(c = *lptr++) || c=='.')
  1043. X                if (p < &idbuf[sizeof(idbuf)-1])
  1044. X                    *p++ = c;
  1045. X            *p = '\0';
  1046. X            lptr--;
  1047. X            return (lookup(idbuf));
  1048. X        }
  1049. X
  1050. X        else if (c == '(') {
  1051. X            pcnt = 0;
  1052. X            do {
  1053. X                c = *lptr++;
  1054. X                if (c == '\0') return(c);
  1055. X                else if (c == '(') pcnt++;
  1056. X                else if (c == ')') pcnt--;
  1057. X            } while (pcnt > 0);
  1058. X        }
  1059. X
  1060. X        else return (*lptr++);
  1061. X    }
  1062. X}
  1063. X
  1064. Xstruct table {
  1065. X    char *name;
  1066. X    int type, value;
  1067. X};
  1068. X
  1069. Xstruct table mdtab[] = {
  1070. X    {"January", MONTH, 1},
  1071. X    {"February", MONTH, 2},
  1072. X    {"March", MONTH, 3},
  1073. X    {"April", MONTH, 4},
  1074. X    {"May", MONTH, 5},
  1075. X    {"June", MONTH, 6},
  1076. X    {"July", MONTH, 7},
  1077. X    {"August", MONTH, 8},
  1078. X    {"September", MONTH, 9},
  1079. X    {"Sept", MONTH, 9},
  1080. X    {"October", MONTH, 10},
  1081. X    {"November", MONTH, 11},
  1082. X    {"December", MONTH, 12},
  1083. X
  1084. X    {"Sunday", DAY, 0},
  1085. X    {"Monday", DAY, 1},
  1086. X    {"Tuesday", DAY, 2},
  1087. X    {"Tues", DAY, 2},
  1088. X    {"Wednesday", DAY, 3},
  1089. X    {"Wednes", DAY, 3},
  1090. X    {"Thursday", DAY, 4},
  1091. X    {"Thur", DAY, 4},
  1092. X    {"Thurs", DAY, 4},
  1093. X    {"Friday", DAY, 5},
  1094. X    {"Saturday", DAY, 6},
  1095. X    {0, 0, 0}};
  1096. X
  1097. X#define HRS *60
  1098. X#define HALFHR 30
  1099. Xstruct table mztab[] = {
  1100. X    {"a.m.", MERIDIAN, AM},
  1101. X    {"am", MERIDIAN, AM},
  1102. X    {"p.m.", MERIDIAN, PM},
  1103. X    {"pm", MERIDIAN, PM},
  1104. X    {"nst", ZONE, 3 HRS + HALFHR},        /* Newfoundland */
  1105. X    {"n.s.t.", ZONE, 3 HRS + HALFHR},
  1106. X    {"ast", ZONE, 4 HRS},        /* Atlantic */
  1107. X    {"a.s.t.", ZONE, 4 HRS},
  1108. X    {"adt", DAYZONE, 4 HRS},
  1109. X    {"a.d.t.", DAYZONE, 4 HRS},
  1110. X    {"est", ZONE, 5 HRS},        /* Eastern */
  1111. X    {"e.s.t.", ZONE, 5 HRS},
  1112. X    {"edt", DAYZONE, 5 HRS},
  1113. X    {"e.d.t.", DAYZONE, 5 HRS},
  1114. X    {"cst", ZONE, 6 HRS},        /* Central */
  1115. X    {"c.s.t.", ZONE, 6 HRS},
  1116. X    {"cdt", DAYZONE, 6 HRS},
  1117. X    {"c.d.t.", DAYZONE, 6 HRS},
  1118. X    {"mst", ZONE, 7 HRS},        /* Mountain */
  1119. X    {"m.s.t.", ZONE, 7 HRS},
  1120. X    {"mdt", DAYZONE, 7 HRS},
  1121. X    {"m.d.t.", DAYZONE, 7 HRS},
  1122. X    {"pst", ZONE, 8 HRS},        /* Pacific */
  1123. X    {"p.s.t.", ZONE, 8 HRS},
  1124. X    {"pdt", DAYZONE, 8 HRS},
  1125. X    {"p.d.t.", DAYZONE, 8 HRS},
  1126. X    {"yst", ZONE, 9 HRS},        /* Yukon */
  1127. X    {"y.s.t.", ZONE, 9 HRS},
  1128. X    {"ydt", DAYZONE, 9 HRS},
  1129. X    {"y.d.t.", DAYZONE, 9 HRS},
  1130. X    {"hst", ZONE, 10 HRS},        /* Hawaii */
  1131. X    {"h.s.t.", ZONE, 10 HRS},
  1132. X    {"hdt", DAYZONE, 10 HRS},
  1133. X    {"h.d.t.", DAYZONE, 10 HRS},
  1134. X
  1135. X    {"gmt", ZONE, 0 HRS},
  1136. X    {"g.m.t.", ZONE, 0 HRS},
  1137. X    {"bst", DAYZONE, 0 HRS},        /* British Summer Time */
  1138. X    {"b.s.t.", DAYZONE, 0 HRS},
  1139. X    {"eet", ZONE, 0 HRS},        /* European Eastern Time */
  1140. X    {"e.e.t.", ZONE, 0 HRS},
  1141. X    {"eest", DAYZONE, 0 HRS},    /* European Eastern Summer Time */
  1142. X    {"e.e.s.t.", DAYZONE, 0 HRS},
  1143. X    {"met", ZONE, -1 HRS},        /* Middle European Time */
  1144. X    {"m.e.t.", ZONE, -1 HRS},
  1145. X    {"mest", DAYZONE, -1 HRS},    /* Middle European Summer Time */
  1146. X    {"m.e.s.t.", DAYZONE, -1 HRS},
  1147. X    {"wet", ZONE, -2 HRS },        /* Western European Time */
  1148. X    {"w.e.t.", ZONE, -2 HRS },
  1149. X    {"west", DAYZONE, -2 HRS},    /* Western European Summer Time */
  1150. X    {"w.e.s.t.", DAYZONE, -2 HRS},
  1151. X
  1152. X    {"jst", ZONE, -9 HRS},        /* Japan Standard Time */
  1153. X    {"j.s.t.", ZONE, -9 HRS},    /* Japan Standard Time */
  1154. X                    /* No daylight savings time */
  1155. X
  1156. X    {"aest", ZONE, -10 HRS},    /* Australian Eastern Time */
  1157. X    {"a.e.s.t.", ZONE, -10 HRS},
  1158. X    {"aesst", DAYZONE, -10 HRS},    /* Australian Eastern Summer Time */
  1159. X    {"a.e.s.s.t.", DAYZONE, -10 HRS},
  1160. X    {"acst", ZONE, -(9 HRS + HALFHR)},    /* Australian Central Time */
  1161. X    {"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
  1162. X    {"acsst", DAYZONE, -(9 HRS + HALFHR)},    /* Australian Central Summer */
  1163. X    {"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
  1164. X    {"awst", ZONE, -8 HRS},        /* Australian Western Time */
  1165. X    {"a.w.s.t.", ZONE, -8 HRS},    /* (no daylight time there, I'm told */
  1166. X    {0, 0, 0}};
  1167. X
  1168. Xstruct table unittb[] = {
  1169. X    {"year", MUNIT, 12},
  1170. X    {"month", MUNIT, 1},
  1171. X    {"fortnight", UNIT, 14*24*60},
  1172. X    {"week", UNIT, 7*24*60},
  1173. X    {"day", UNIT, 1*24*60},
  1174. X    {"hour", UNIT, 60},
  1175. X    {"minute", UNIT, 1},
  1176. X    {"min", UNIT, 1},
  1177. X    {"second", SUNIT, 1},
  1178. X    {"sec", SUNIT, 1},
  1179. X    {0, 0, 0}};
  1180. X
  1181. Xstruct table othertb[] = {
  1182. X    {"tomorrow", UNIT, 1*24*60},
  1183. X    {"yesterday", UNIT, -1*24*60},
  1184. X    {"today", UNIT, 0},
  1185. X    {"now", UNIT, 0},
  1186. X    {"last", NUMBER, -1},
  1187. X    {"this", UNIT, 0},
  1188. X    {"next", NUMBER, 2},
  1189. X    {"first", NUMBER, 1},
  1190. X    /* {"second", NUMBER, 2}, */
  1191. X    {"third", NUMBER, 3},
  1192. X    {"fourth", NUMBER, 4},
  1193. X    {"fifth", NUMBER, 5},
  1194. X    {"sixth", NUMBER, 6},
  1195. X    {"seventh", NUMBER, 7},
  1196. X    {"eigth", NUMBER, 8},
  1197. X    {"ninth", NUMBER, 9},
  1198. X    {"tenth", NUMBER, 10},
  1199. X    {"eleventh", NUMBER, 11},
  1200. X    {"twelfth", NUMBER, 12},
  1201. X    {"ago", AGO, 1},
  1202. X    {0, 0, 0}};
  1203. X
  1204. Xstruct table milzone[] = {
  1205. X    {"a", ZONE, 1 HRS},
  1206. X    {"b", ZONE, 2 HRS},
  1207. X    {"c", ZONE, 3 HRS},
  1208. X    {"d", ZONE, 4 HRS},
  1209. X    {"e", ZONE, 5 HRS},
  1210. X    {"f", ZONE, 6 HRS},
  1211. X    {"g", ZONE, 7 HRS},
  1212. X    {"h", ZONE, 8 HRS},
  1213. X    {"i", ZONE, 9 HRS},
  1214. X    {"k", ZONE, 10 HRS},
  1215. X    {"l", ZONE, 11 HRS},
  1216. X    {"m", ZONE, 12 HRS},
  1217. X    {"n", ZONE, -1 HRS},
  1218. X    {"o", ZONE, -2 HRS},
  1219. X    {"p", ZONE, -3 HRS},
  1220. X    {"q", ZONE, -4 HRS},
  1221. X    {"r", ZONE, -5 HRS},
  1222. X    {"s", ZONE, -6 HRS},
  1223. X    {"t", ZONE, -7 HRS},
  1224. X    {"u", ZONE, -8 HRS},
  1225. X    {"v", ZONE, -9 HRS},
  1226. X    {"w", ZONE, -10 HRS},
  1227. X    {"x", ZONE, -11 HRS},
  1228. X    {"y", ZONE, -12 HRS},
  1229. X    {"z", ZONE, 0 HRS},
  1230. X    {0, 0, 0}};
  1231. X
  1232. Xlookup(id) char *id;
  1233. X{
  1234. X#define gotit (yylval=i->value,  i->type)
  1235. X#define getid for(j=idvar, k=id; *j++ = *k++; )
  1236. X
  1237. X    char idvar[20];
  1238. X    register char *j, *k;
  1239. X    register struct table *i;
  1240. X    int abbrev;
  1241. X
  1242. X    getid;
  1243. X    if (strlen(idvar) == 3) abbrev = 1;
  1244. X    else if (strlen(idvar) == 4 && idvar[3] == '.') {
  1245. X        abbrev = 1;
  1246. X        idvar[3] = '\0';
  1247. X    }
  1248. X    else abbrev = 0;
  1249. X
  1250. X    if (islower(*idvar)) *idvar = toupper(*idvar);
  1251. X
  1252. X    for (i = mdtab; i->name; i++) {
  1253. X        k = idvar;
  1254. X        for (j = i->name; *j++ == *k++;) {
  1255. X            if (abbrev && j==i->name+3) return gotit;
  1256. X            if (j[-1] == 0) return gotit;
  1257. X        }
  1258. X    }
  1259. X
  1260. X    getid;
  1261. X    for (i = mztab; i->name; i++)
  1262. X        if (strcmp(i->name, idvar) == 0) return gotit;
  1263. X
  1264. X    for (j = idvar; *j; j++)
  1265. X        if (isupper(*j)) *j = tolower(*j);
  1266. X    for (i=mztab; i->name; i++)
  1267. X        if (strcmp(i->name, idvar) == 0) return gotit;
  1268. X
  1269. X    getid;
  1270. X    for (i=unittb; i->name; i++)
  1271. X        if (strcmp(i->name, idvar) == 0) return gotit;
  1272. X
  1273. X    if (idvar[strlen(idvar)-1] == 's')
  1274. X        idvar[strlen(idvar)-1] = '\0';
  1275. X    for (i=unittb; i->name; i++)
  1276. X        if (strcmp(i->name, idvar) == 0) return gotit;
  1277. X
  1278. X    getid;
  1279. X    for (i = othertb; i->name; i++)
  1280. X        if (strcmp(i->name, idvar) == 0) return gotit;
  1281. X
  1282. X    getid;
  1283. X    if (strlen(idvar) == 1 && isalpha(*idvar)) {
  1284. X        if (isupper(*idvar)) *idvar = tolower(*idvar);
  1285. X        for (i = milzone; i->name; i++)
  1286. X            if (strcmp(i->name, idvar) == 0) return gotit;
  1287. X    }
  1288. X
  1289. X    return(ID);
  1290. X}
  1291. X
  1292. Xtime_t getdate(p, now, zone) char *p; time_t now; long zone;
  1293. X{
  1294. X#define mcheck(f)    if (f>1) err++
  1295. X    time_t monthadd();
  1296. X    int err;
  1297. X    struct tm *lt;
  1298. X    time_t sdate, tod;
  1299. X
  1300. X    lptr = p;
  1301. X    if (now <= 0)
  1302. X        (void) time(&now);
  1303. X    lt = localtime(&now);
  1304. X    year = lt->tm_year;
  1305. X    month = lt->tm_mon+1;
  1306. X    day = lt->tm_mday;
  1307. X    relsec = 0; relmonth = 0;
  1308. X    timeflag=zoneflag=dateflag=dayflag=relflag=0;
  1309. X    daylight = MAYBE;
  1310. X    hh = mm = ss = 0;
  1311. X    merid = 24;
  1312. X    ourzone = zone;
  1313. X
  1314. X    if (err = yyparse()) return (-1);
  1315. X
  1316. X    mcheck(timeflag);
  1317. X    mcheck(zoneflag);
  1318. X    mcheck(dateflag);
  1319. X    mcheck(dayflag);
  1320. X
  1321. X    if (err) return (-1);
  1322. X    if (dateflag || timeflag || dayflag) {
  1323. X        sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylight);
  1324. X        if (sdate < 0) return -1;
  1325. X    }
  1326. X    else {
  1327. X        sdate = now;
  1328. X        if (relflag == 0)
  1329. X            sdate -= (lt->tm_sec + lt->tm_min*60 +
  1330. X                lt->tm_hour*(60L*60L));
  1331. X    }
  1332. X
  1333. X    sdate += relsec;
  1334. X    sdate += monthadd(sdate, relmonth);
  1335. X
  1336. X    if (dayflag && !dateflag) {
  1337. X        tod = dayconv(dayord, dayreq, sdate);
  1338. X        sdate += tod;
  1339. X    }
  1340. X
  1341. X    return sdate;
  1342. X}
  1343. X
  1344. Xyyerror(s) char *s;
  1345. X{}
  1346. END_OF_FILE
  1347.   if test 12373 -ne `wc -c <'getdate.y'`; then
  1348.     echo shar: \"'getdate.y'\" unpacked with wrong size!
  1349.   fi
  1350.   # end of 'getdate.y'
  1351. fi
  1352. if test -f 'help.c' -a "${1}" != "-c" ; then 
  1353.   echo shar: Will not clobber existing file \"'help.c'\"
  1354. else
  1355.   echo shar: Extracting \"'help.c'\" \(15622 characters\)
  1356.   sed "s/^X//" >'help.c' <<'END_OF_FILE'
  1357. X/* $Header: help.c,v 4.3.3.1 90/07/24 21:52:37 davison Trn $
  1358. X *
  1359. X * $Log:    help.c,v $
  1360. X * Revision 4.3.3.1  90/07/24  21:52:37  davison
  1361. X * Initial Trn Release
  1362. X * 
  1363. X * Revision 4.3.1.2  85/09/10  11:05:39  lwall
  1364. X * Improved %m in in_char().
  1365. X * 
  1366. X * Revision 4.3.1.1  85/05/10  11:33:10  lwall
  1367. X * Branch for patches.
  1368. X * 
  1369. X * Revision 4.3  85/05/01  11:38:59  lwall
  1370. X * Baseline for release with 4.3bsd.
  1371. X * 
  1372. X */
  1373. X
  1374. X#include "EXTERN.h"
  1375. X#include "common.h"
  1376. X#include "rn.h"
  1377. X#include "term.h"
  1378. X#include "INTERN.h"
  1379. X#include "help.h"
  1380. X
  1381. Xvoid
  1382. Xhelp_init()
  1383. X{
  1384. X    ;
  1385. X}
  1386. X
  1387. Xint
  1388. Xhelp_page()
  1389. X{
  1390. X    int cmd;
  1391. X
  1392. X#ifdef PAGERHELP
  1393. X    doshell(sh,filexp(PAGERHELP));
  1394. X#else
  1395. X    page_init();
  1396. X    if ((cmd = print_lines("\
  1397. XPaging commands:\n\
  1398. X",STANDOUT)) ||
  1399. X    (cmd = print_lines("\n\
  1400. XSP    Display the next page.\n\
  1401. Xx    Display the next page decrypted (rot13).\n\
  1402. Xd    Display half a page more.\n\
  1403. XCR    Display one more line.\n\
  1404. X^R,v,^X    Restart the current article (v=verbose header, ^X=rot13).\n\
  1405. X",NOMARKING)) ||
  1406. X    (cmd = print_lines("\
  1407. Xb    Back up one page.\n\
  1408. X^L,X    Refresh the screen (X=rot13).\n\
  1409. X",NOMARKING)) ||
  1410. X#ifdef USETHREADS
  1411. X    (cmd = print_lines("\
  1412. Xt    Display the entire article tree and all its subjects.\n\
  1413. X",NOMARKING)) ||
  1414. X#endif
  1415. X    (cmd = print_lines("\
  1416. Xg pat    Go to (search forward within article for) pattern.\n\
  1417. XG    Search again for current pattern within article.\n\
  1418. X^G    Search for next line beginning with \"Subject:\".\n\
  1419. XTAB    Search for next line beginning with a different character.\n\
  1420. Xq    Quit the pager, go to end of article.  Leave article read or unread.\n\
  1421. Xj    Junk this article (mark it read).  Goes to end of article.\n\
  1422. X\n\
  1423. X",NOMARKING)) ||
  1424. X    (cmd = print_lines("\
  1425. XThe following commands skip the rest of the current article, then behave\n\
  1426. Xjust as if typed to the 'What next?' prompt at the end of the article:\n\
  1427. X",STANDOUT)) ||
  1428. X    (cmd = print_lines("\n\
  1429. Xn    Scan forward for next unread article.\n\
  1430. XN    Go to next article.\n\
  1431. X^N    Scan forward for next unread article with same title.\n\
  1432. Xp,P,^P    Same as n,N,^N, only going backwards.\n\
  1433. X-    Go to previously displayed article.\n\
  1434. X",NOMARKING)) ||
  1435. X#ifdef USETHREADS
  1436. X    (cmd = print_lines("\
  1437. X<,>    Browse the previous/next selected thread.  If no threads are selected,\n\
  1438. X    all threads that had unread news upon entry to the group are considered\n\
  1439. X    selected for browsing.  Entering an empty group browses all threads.\n\
  1440. X[,],{,} Go to parent/child/root/leaf in thread.\n\
  1441. X\n\
  1442. X",NOMARKING)) ||
  1443. X#endif
  1444. X    (cmd = print_lines("\
  1445. XThe following commands also take you to the end of the article.\n\
  1446. XType h at end of article for a description of these commands:\n\
  1447. X",STANDOUT)) ||
  1448. X#ifdef USETHREADS
  1449. X    (cmd = print_lines("\
  1450. X    # $ & / = ? c C f F k K ^K J , m M number e r R ^R s S u U v w W Y ^ |\n\
  1451. X\n\
  1452. X(To return to the middle of the article after one of these commands, type ^L.)\n\
  1453. X",NOMARKING)) )
  1454. X#else
  1455. X    (cmd = print_lines("\
  1456. X    # $ & / = ? c C f F k K ^K m M number e r R ^R s S u v w W Y ^ |\n\
  1457. X\n\
  1458. X(To return to the middle of the article after one of these commands, type ^L.)\n\
  1459. X",NOMARKING)) )
  1460. X#endif
  1461. X    return cmd;
  1462. X#endif
  1463. X    return 0;
  1464. X}
  1465. X
  1466. Xint
  1467. Xhelp_art()
  1468. X{
  1469. X    int cmd;
  1470. X#ifdef ARTHELP
  1471. X    doshell(sh,filexp(ARTHELP));
  1472. X#else
  1473. X    page_init();
  1474. X    if ((cmd = print_lines("\
  1475. XArticle Selection commands:\n\
  1476. X",STANDOUT)) ||
  1477. X#ifdef USETHREADS
  1478. X    (cmd = print_lines("\n\
  1479. Xn,SP    Find next unread article (follows discussion-tree in threaded groups).\n\
  1480. X",NOMARKING)) ||
  1481. X#else
  1482. X    (cmd = print_lines("\n\
  1483. Xn,SP    Scan forward for next unread article.\n\
  1484. X",NOMARKING)) ||
  1485. X#endif
  1486. X    (cmd = print_lines("\
  1487. XN    Go to next article.\n\
  1488. X^N    Scan forward for next unread article with same subject.\n\
  1489. Xp,P,^P    Same as n,N,^N, only going backwards.\n\
  1490. X-    Go to previously displayed article.\n\
  1491. X",NOMARKING)) ||
  1492. X#ifdef USETHREADS
  1493. X    (cmd = print_lines("\
  1494. X<,>    Browse the previous/next selected thread.  If no threads are selected,\n\
  1495. X    all threads that had unread news upon entry to the group are considered\n\
  1496. X    selected for browsing.  Entering an empty group browses all threads.\n\
  1497. X[,]    Go to article's parent/child.\n\
  1498. X{,}    Go to tree's root/leaf.\n\
  1499. Xt    Display the entire article tree and all its subjects.\n\
  1500. X",NOMARKING)) ||
  1501. X#endif
  1502. X    (cmd = print_lines("\
  1503. Xnumber    Go to specified article.\n\
  1504. Xrange{,range}:command{:command}\n\
  1505. X    Apply one or more commands to one or more ranges of articles.\n\
  1506. X    Ranges are of the form: number | number-number.  You may use . for\n\
  1507. X    the current article, and $ for the last article.\n\
  1508. X",NOMARKING)) ||
  1509. X#ifdef USETHREADS
  1510. X    (cmd = print_lines("\
  1511. X     Valid commands are: e, j, m, M, s, S, t, T, |, +, and -.\n\
  1512. X:cmd    Perform a command on all the selected articles.\n\
  1513. X",NOMARKING)) ||
  1514. X#else
  1515. X    (cmd = print_lines("\
  1516. X     Valid commands are: e, j, m, M, s, S, and |.\n\
  1517. X",NOMARKING)) ||
  1518. X#endif
  1519. X    (cmd = print_lines("\
  1520. X/pattern/modifiers\n\
  1521. X    Scan forward for article containing pattern in the subject line.\n\
  1522. X    (Use ?pat? to scan backwards; append h to scan headers, a to scan\n\
  1523. X    entire articles, r to scan read articles, c to make case sensitive.)\n\
  1524. X",NOMARKING)) ||
  1525. X    (cmd = print_lines("\
  1526. X/pattern/modifiers:command{:command}\n\
  1527. X    Apply one or more commands to the set of articles matching pattern.\n\
  1528. X    Use a K modifier to save entire command to the KILL file for this\n\
  1529. X    newsgroup.  Commands m and M, if first, imply an r modifier.\n\
  1530. X     Valid commands are the same as for the range command.\n\
  1531. X",NOMARKING)) ||
  1532. X    (cmd = print_lines("\
  1533. Xf,F    Submit a followup article (F = include this article).\n\
  1534. Xr,R    Reply through net mail (R = include this article).\n\
  1535. Xe dir{|command}\n\
  1536. X    Extract to directory using /bin/sh, uudecode, or specified command.\n\
  1537. Xs ...    Save to file or pipe via sh.\n\
  1538. XS ...    Save via preferred shell.\n\
  1539. Xw,W    Like s and S but save without the header.\n\
  1540. X| ...    Same as s|...\n\
  1541. X",NOMARKING)) ||
  1542. X    (cmd = print_lines("\
  1543. XC    Cancel this article, if yours.\n\
  1544. X^R,v    Restart article (v=verbose).\n\
  1545. X^X    Restart article, rot13 mode.\n\
  1546. Xc    Catch up (mark all articles as read).\n\
  1547. Xb    Back up one page.\n\
  1548. X^L    Refresh the screen.  You can get back to the pager with this.\n\
  1549. XX    Refresh screen in rot13 mode.\n\
  1550. X",NOMARKING)) ||
  1551. X    (cmd = print_lines("\
  1552. X^    Go to first unread article.  Disables subject search mode.\n\
  1553. X$    Go to end of newsgroup.  Disables subject search mode.\n\
  1554. X",NOMARKING)) ||
  1555. X    (cmd = print_lines("#       Print last article number.\n\
  1556. X&    Print current values of command-line switches.\n\
  1557. X&switch {switch}\n\
  1558. X    Set or unset more switches.\n\
  1559. X&&    Print current macro definitions.\n\
  1560. X&&def    Define a new macro.\n\
  1561. Xj    Junk this article (mark it read).  Stays at end of article.\n\
  1562. X",NOMARKING)) ||
  1563. X    (cmd = print_lines("\
  1564. Xm    Mark article as still unread.\n\
  1565. XM    Mark article as still unread upon exiting newsgroup or Y command.\n\
  1566. XY    Yank back articles marked temporarily read via M.\n\
  1567. Xk    Kill current subject (mark articles as read).\n\
  1568. X",NOMARKING)) ||
  1569. X#ifdef USETHREADS
  1570. X    (cmd = print_lines("\
  1571. X,    Mark current article and its replies as read.\n\
  1572. XJ    Junk entire thread (mark all subjects as read in this thread).\n\
  1573. XT    Trash current thread (like 'J'), and save command in KILL file.\n\
  1574. X",NOMARKING)) ||
  1575. X#endif
  1576. X    (cmd = print_lines("\
  1577. XK    Mark current subject as read, and save command in KILL file.\n\
  1578. X^K    Edit local KILL file (the one for this newsgroup).\n\
  1579. X=    List subjects of unread articles.\n\
  1580. X",NOMARKING)) ||
  1581. X#ifdef USETHREADS
  1582. X    (cmd = print_lines("\
  1583. X+    Enter thread selection mode.\n\
  1584. XU    Unread some news -- prompts for thread, subthread, all, or select.\n\
  1585. X",NOMARKING)) ||
  1586. X#endif
  1587. X    (cmd = print_lines("\
  1588. Xu    Unsubscribe from this newsgroup.\n\
  1589. Xq    Quit this newsgroup for now.\n\
  1590. XQ    Quit newsgroup, staying at current newsgroup.\n\
  1591. X",NOMARKING)) )
  1592. X    return cmd;
  1593. X#endif
  1594. X    return 0;
  1595. X}
  1596. X
  1597. Xint
  1598. Xhelp_ng()
  1599. X{
  1600. X    int cmd;
  1601. X#ifdef NGHELP
  1602. X    doshell(sh,filexp(NGHELP));
  1603. X#else
  1604. X    page_init();
  1605. X    if (cmd = print_lines("\
  1606. XNewsgroup Selection commands:\n\
  1607. X",STANDOUT) )
  1608. X    return cmd;
  1609. X    if (ng != nextrcline) {
  1610. X    if ((cmd = print_lines("\
  1611. X\n\
  1612. Xy,SP    Do this newsgroup now.\n\
  1613. X.cmd    Do this newsgroup, executing cmd as first command.\n\
  1614. X",NOMARKING)) ||
  1615. X#ifdef USETHREADS
  1616. X    (cmd = print_lines("\
  1617. X+    Enter this newsgroup through the thread selector (like typing .+<CR>).\n\
  1618. X",NOMARKING)) ||
  1619. X#endif
  1620. X    (cmd = print_lines("\
  1621. X=    Start this newsgroup, but list subjects before reading articles.\n\
  1622. X",NOMARKING)) ||
  1623. X#ifdef USETHREADS
  1624. X    (cmd = print_lines("\
  1625. XU    Enter this newsgroup by way of the \"Set unread?\" prompt.\n\
  1626. X",NOMARKING)) ||
  1627. X#endif
  1628. X    (cmd = print_lines("\
  1629. Xu    Unsubscribe from this newsgroup.\n\
  1630. X",NOMARKING)) )
  1631. X        return cmd;
  1632. X    }
  1633. X    if ((cmd = print_lines("\
  1634. Xc    Catch up (mark this newsgroup all read).\n\
  1635. X\n\
  1636. Xn    Go to the next newsgroup with unread news.\n\
  1637. XN    Go to the next newsgroup.\n\
  1638. Xp    Go to the previous newsgroup with unread news.\n\
  1639. XP    Go to the previous newsgroup.\n\
  1640. X",NOMARKING)) ||
  1641. X    (cmd = print_lines("\
  1642. X-    Go to the previously displayed newsgroup.\n\
  1643. X1    Go to the first newsgroup.\n\
  1644. X^    Go to the first newsgroup with unread news.\n\
  1645. X$    Go to the last newsgroup.\n\
  1646. X",NOMARKING)) ||
  1647. X    (cmd = print_lines("\
  1648. Xg name    Go to the named newsgroup.  Subscribe to new newsgroups this way too.\n\
  1649. X/pat    Search forward for newsgroup matching pattern.\n\
  1650. X?pat    Search backward for newsgroup matching pattern.\n\
  1651. X    (Use * and ? style patterns.  Append r to include read newsgroups.)\n\
  1652. X",NOMARKING)) ||
  1653. X    (cmd = print_lines("\
  1654. Xl pat    List unsubscribed newsgroups containing pattern.\n\
  1655. Xm name    Move named newsgroup elsewhere (no name moves current newsgroup).\n\
  1656. Xo pat    Only display newsgroups matching pattern.  Omit pat to unrestrict.\n\
  1657. Xa pat    Like o, but also scans for unsubscribed newsgroups matching pattern.\n\
  1658. XL    List current .newsrc.\n\
  1659. X",NOMARKING)) ||
  1660. X    (cmd = print_lines("\
  1661. X&    Print current command-line switch settings.\n\
  1662. X&switch {switch}\n\
  1663. X    Set (or unset) more command-line switches.\n\
  1664. X&&    Print current macro definitions.\n\
  1665. X&&def    Define a new macro.\n\
  1666. X!cmd    Shell escape.\n\
  1667. X",NOMARKING)) ||
  1668. X    (cmd = print_lines("\
  1669. Xq    Quit trn.\n\
  1670. Xx    Quit, restoring .newsrc to its state at startup of trn.\n\
  1671. X^K    Edit the global KILL file.  Use commands like /pattern/j to suppress\n\
  1672. X    pattern in every newsgroup.\n\
  1673. Xv    Print version.\n\
  1674. X",NOMARKING)) )
  1675. X    return cmd;
  1676. X#endif
  1677. X#ifdef PUSHBACK
  1678. X    if (cmd = get_anything())
  1679. X    return cmd;
  1680. X    show_macros();
  1681. X#endif
  1682. X    return 0;
  1683. X}
  1684. X
  1685. X#ifdef ESCSUBS
  1686. Xint
  1687. Xhelp_subs()
  1688. X{
  1689. X    int cmd;
  1690. X#ifdef SUBSHELP
  1691. X    doshell(sh,filexp(SUBSHELP));
  1692. X#else
  1693. X    page_init();
  1694. X    if ((cmd = print_lines("\
  1695. XValid substitutions are:\n\
  1696. X",STANDOUT)) ||
  1697. X    (cmd = print_lines("\
  1698. X\n\
  1699. Xa    Current article number\n\
  1700. XA    Full name of current article (%P/%c/%a)\n\
  1701. Xb    Destination of last save command, often a mailbox\n\
  1702. XB    Bytes to ignore at beginning of last saved article\n\
  1703. X",NOMARKING)) ||
  1704. X    (cmd = print_lines("\
  1705. Xc    Current newsgroup, directory form\n\
  1706. XC    Current newsgroup, dot form\n\
  1707. Xd    Full name of newsgroup directory (%P/%c)\n\
  1708. XD    Distribution line from current article\n\
  1709. Xe    The last command executed to extract data from an article\n\
  1710. XE    The number of extra (unselected) articles, not counting the current\n\
  1711. X    one if it is unselected\n\
  1712. X",NOMARKING)) ||
  1713. X    (cmd = print_lines("\
  1714. Xf    Who the current article is from\n\
  1715. XF    Newsgroups to followup to (from Newsgroups and Followup-To)\n\
  1716. Xh    (This help message)\n\
  1717. XH    Host name (yours)\n\
  1718. Xi    Message-I.D. line from current article, with <>\n\
  1719. XI    Reference indicator mark (see -F switch)\n\
  1720. X",NOMARKING)) ||
  1721. X    (cmd = print_lines("\
  1722. Xl    News administrator's login name, if any\n\
  1723. XL    Login name (yours)\n\
  1724. X",NOMARKING)) ||
  1725. X#ifdef USETHREADS
  1726. X    (cmd = print_lines("\
  1727. Xm    Current mode, first letter of (init,newsgroup,thread,article,pager,\n\
  1728. X        unread,Add,Catchup,Delete-bogus,Mailbox,Resubscribe)\n\
  1729. X",NOMARKING)) ||
  1730. X#else
  1731. X    (cmd = print_lines("\
  1732. Xm    Current mode, first letter of (init, newsgroup, article, pager,\n\
  1733. X        Add, Catchup, Delete bogus, Mailbox, Resubscribe)\n\
  1734. X",NOMARKING)) ||
  1735. X#endif
  1736. X    (cmd = print_lines("\
  1737. XM    Number of article marked with M\n\
  1738. Xn    Newsgroups from current article\n\
  1739. XN    Full name (yours)\n\
  1740. X",NOMARKING)) ||
  1741. X    (cmd = print_lines("\
  1742. Xo    Organization (yours)\n\
  1743. XO    Original working directory (where you ran trn from)\n\
  1744. Xp    Your private news directory (from -d)\n\
  1745. XP    Public news spool directory\n\
  1746. X",NOMARKING)) ||
  1747. X    (cmd = print_lines("\
  1748. Xr    Last reference (parent article id)\n\
  1749. XR    References list for followup article\n\
  1750. Xs    Subject, with all Re's and (nf)'s stripped off\n\
  1751. XS    Subject, with one Re stripped off\
  1752. X",NOMARKING)) ||
  1753. X    (cmd = print_lines("\
  1754. Xt    New To line derived from From and Reply-To (Internet format)\n\
  1755. XT    New To line derived from Path\n\
  1756. Xu    Number of unread articles\n\
  1757. XU    Number of unread articles not counting the current article (when\n\
  1758. X    threads are selected, the count only reflects selected articles)\n\
  1759. Xx    News library directory\n\
  1760. XX    Trn library directory\n\
  1761. Xz    Length of current article in bytes\n\
  1762. XZ    Number of selected threads\n\
  1763. X",NOMARKING)) ||
  1764. X    (cmd = print_lines("\
  1765. X~    Your home directory\n\
  1766. X.    Directory containing . files\n\
  1767. X#    A counter in multiple-article commands\n\
  1768. X$    Current process number\n\
  1769. X/    Last search string\n\
  1770. XESC    Run preceding command through % interpretation\n\
  1771. X",NOMARKING)) )
  1772. X    return cmd;
  1773. X#endif
  1774. X    return 0;
  1775. X}
  1776. X#endif
  1777. X
  1778. X#ifdef USETHREADS
  1779. Xint
  1780. Xhelp_select()
  1781. X{
  1782. X    int cmd;
  1783. X
  1784. X    page_init();
  1785. X    if ((cmd = print_lines("\
  1786. XThread selection commands:\n\
  1787. X",STANDOUT)) ||
  1788. X    (cmd = print_lines("\n\
  1789. Xa-z,0-9    Select/deselect the discussion thread by its letter or number.  By\n\
  1790. X    default the letters h, k, m, n, p, q and y are omitted.\n\
  1791. XSP    Perform the default command (usually > or Z).\n\
  1792. XCR    Start reading.  Selects the current thread if none are selected.\n\
  1793. XZ,TAB    Start reading.  If no articles are selected, read everything.\n\
  1794. Xy, '.'    Toggle the current thread's selection.\n\
  1795. Xk, ','    Mark the current thread as killed.\n\
  1796. X",NOMARKING)) ||
  1797. X    (cmd = print_lines("\
  1798. Xm, \\    Unmark the current thread.\n\
  1799. X-    Set a range, as in 2 - 5.  Repeats the last marking action.\n\
  1800. X@    Toggle all visible thread selections.\n\
  1801. Xn, ]    Move down to the next thread.\n\
  1802. Xp, [    Move up to the previous thread.\n\
  1803. X<, >    Go to previous/next page.\n\
  1804. X^, $    Go to first/last page.\n\
  1805. X",NOMARKING)) ||
  1806. X    (cmd = print_lines("\
  1807. XX    Mark all unselected articles as read and start reading.\n\
  1808. XD    Mark unselected articles on the current page as read.  Start\n\
  1809. X    reading if articles were selected, else go to next page.\n\
  1810. XJ    Junk all selected articles (mark them as read).\n\
  1811. X^K    Edit local KILL file (the one for this newsgroup).\n\
  1812. X:cmd    Perform a command on all the selected articles.\n\
  1813. X",NOMARKING)) ||
  1814. X    (cmd = print_lines("\
  1815. X/pattern/modifiers\n\
  1816. X    Scan all articles for a subject containing pattern.\n\
  1817. X    (Append h to scan headers, a to scan entire articles, c to make case\n\
  1818. X    sensitive, r to scan read articles (assumed when you are selecting\n\
  1819. X    read articles to set unread.)\n\
  1820. X/pattern/modifiers:command{:command}\n\
  1821. X    Apply one or more commands to the set of articles matching pattern.\n\
  1822. X",NOMARKING)) ||
  1823. X    (cmd = print_lines("\
  1824. X    Use a K modifier to save entire command to the KILL file for this\n\
  1825. X    newsgroup.  Commands m and M, if first, imply an r modifier.\n\
  1826. X     Valid commands are: e, j, m, M, s, S, T, !, and the thread selection\n\
  1827. X    commands: + and -.\n\
  1828. XN    Leave this group as-is and go on to the next.\n\
  1829. XU    Switch between selecting read/unread articles.\n\
  1830. XL    Switch the current display mode between a terse mode without\n\
  1831. X    authors and a short and long mode with authors.\n\
  1832. X",NOMARKING)) ||
  1833. X    (cmd = print_lines("\
  1834. X&    View or set command line switches.\n\
  1835. X&&    View or set macro definitions.\n\
  1836. X!cmd    Escape to a subshell.\n\
  1837. Xq    Quit selection mode.\n\
  1838. XQ    Quit group and return to news group selection prompt for this group.\n\
  1839. X",NOMARKING)) )
  1840. X    return cmd;
  1841. X    return 0;
  1842. X}
  1843. X#endif
  1844. END_OF_FILE
  1845.   if test 15622 -ne `wc -c <'help.c'`; then
  1846.     echo shar: \"'help.c'\" unpacked with wrong size!
  1847.   fi
  1848.   # end of 'help.c'
  1849. fi
  1850. if test -f 'rn.c' -a "${1}" != "-c" ; then 
  1851.   echo shar: Will not clobber existing file \"'rn.c'\"
  1852. else
  1853.   echo shar: Extracting \"'rn.c'\" \(14789 characters\)
  1854.   sed "s/^X//" >'rn.c' <<'END_OF_FILE'
  1855. X/*  rn -- new readnews program
  1856. X *
  1857. X *  Original Author: lwall@sdcrdcf.UUCP (Larry Wall)
  1858. X *  Organization: System Development Corporation, Santa Monica
  1859. X *
  1860. X *  begun:   01/14/83
  1861. X *    1.0: 04/08/83
  1862. X *      2.0: 09/01/83
  1863. X *      RRN/RN: 11/01/89
  1864. X*/
  1865. X
  1866. Xstatic char rnid[] = "@(#)$Header: rn.c,v 4.3.3.4 91/06/26 02:25:34 davison Trn $";
  1867. Xstatic char patchlevel[] = "Trn v1.0.3 based on Rn patchlevel 54";
  1868. X
  1869. X/* $Log:    rn.c,v $
  1870. X * Revision 4.3.3.4  91/06/26  02:25:34  davison
  1871. X * Misc. fixes for minor problems.
  1872. X * 
  1873. X * Revision 4.3.3.3  91/01/16  03:28:42  davison
  1874. X * Integrated rn patches 48-54.  Fixed in_char and verify interaction.
  1875. X * 
  1876. X * Revision 4.3.3.2  90/08/20  16:48:19  davison
  1877. X * Changed unthreaded group's default action, version #, email address.
  1878. X * 
  1879. X * Revision 4.3.3.1  90/07/21  20:31:38  davison
  1880. X * Initial Trn Release
  1881. X * 
  1882. X * Revision 4.3.2.11  91/01/04  22:58:24  sob
  1883. X * Checkpoint for patch 54
  1884. X * 
  1885. X * Revision 4.3.2.10  90/12/30  22:58:24  sob
  1886. X * Checkpoint for patch 53
  1887. X * 
  1888. X * Revision 4.3.2.9  90/12/13  22:58:24  sob
  1889. X * Checkpoint for patch 52
  1890. X * 
  1891. X * Revision 4.3.2.8  90/12/10  01:35:43  sob
  1892. X * Checkpoint for patch 51
  1893. X * 
  1894. X * Revision 4.3.2.7  90/11/23  20:30:43  sob
  1895. X * Checkpoint for patch 50
  1896. X * 
  1897. X * Revision 4.3.2.6  90/11/22  13:55:23  sob
  1898. X * Checkpoint for patch #49
  1899. X * 
  1900. X * Revision 4.3.2.5  90/11/06  01:19:43  sob
  1901. X * Checkpoint for patch 48
  1902. X * 
  1903. X * Revision 4.3.2.4  90/04/03  23:11:33  sob
  1904. X * Added more information to the version command.
  1905. X * 
  1906. X * Revision 4.3.2.3  90/03/22  23:05:23  sob
  1907. X * Fixes provided by Wayne Davison <drivax!davison>
  1908. X * 
  1909. X * Revision 4.3.2.2  89/11/28  01:51:25  sob
  1910. X * Removed redundant #include directive.
  1911. X * 
  1912. X * Revision 4.3.2.1  89/11/08  02:27:38  sob
  1913. X * Release of RN 4.3 with RRN that can be compiled from the same
  1914. X * sources as either version of the program.
  1915. X * 
  1916. X * Revision 4.3.1.4  85/09/10  11:05:13  lwall
  1917. X * Improved %m in in_char().
  1918. X * 
  1919. X * Revision 4.3.1.3  85/05/16  16:47:10  lwall
  1920. X * Catchup confirmation didn't grok -t.
  1921. X * 
  1922. X * Revision 4.3.1.2  85/05/13  09:34:53  lwall
  1923. X * Fixed default after do_newsgroup() returns from Q command.
  1924. X * 
  1925. X * Revision 4.3.1.1  85/05/10  11:38:08  lwall
  1926. X * Branch for patches.
  1927. X * 
  1928. X * Revision 4.3  85/05/01  11:47:56  lwall
  1929. X * Baseline for release with 4.3bsd.
  1930. X * 
  1931. X */
  1932. X
  1933. X#include "INTERN.h"
  1934. X#include "common.h"
  1935. X#include "rn.h"
  1936. X#include "EXTERN.h"
  1937. X#include "rcstuff.h"
  1938. X#include "term.h"
  1939. X#include "final.h"
  1940. X#include "ngdata.h"
  1941. X#include "util.h"
  1942. X#include "only.h"
  1943. X#include "ngsrch.h"
  1944. X#include "help.h"
  1945. X#include "last.h"
  1946. X#include "init.h"
  1947. X#include "intrp.h"
  1948. X#include "rcln.h"
  1949. X#include "sw.h"
  1950. X#include "addng.h"
  1951. X#include "ng.h"
  1952. X
  1953. Xvoid
  1954. Xrn_init()
  1955. X{
  1956. X    ;
  1957. X}
  1958. X
  1959. Xvoid
  1960. Xmain(argc,argv)
  1961. Xint argc;
  1962. Xchar *argv[];
  1963. X{
  1964. X    bool foundany;
  1965. X    register char *s;
  1966. X    bool oh_for_the_good_old_days = FALSE;
  1967. X
  1968. X#if defined(USETHREADS) && !THREAD_INIT
  1969. X    /* Default to threaded operation if our name starts with a 't' */
  1970. X    if ((s = rindex(argv[0],'/')) == Nullch)
  1971. X    s = argv[0];
  1972. X    else
  1973. X    s++;
  1974. X    if (*s == 't')
  1975. X    use_threads = TRUE;
  1976. X#endif
  1977. X    foundany = initialize(argc,argv);
  1978. X
  1979. X    if (maxngtodo)
  1980. X    starthere = 0;
  1981. X    else if (!foundany) {        /* nothing to do? */
  1982. X#ifdef VERBOSE
  1983. X    if (verbose)
  1984. X        fputs("\
  1985. XNo unread news in subscribed-to newsgroups.  To subscribe to a new\n\
  1986. Xnewsgroup use the g<newsgroup> command.\n\
  1987. X",stdout) FLUSH;
  1988. X#endif
  1989. X    starthere = nextrcline;
  1990. X    }
  1991. X
  1992. X    /* loop through all unread news */
  1993. X
  1994. X    {
  1995. X    char promptbuf[80];
  1996. X    bool special = FALSE;        /* temporarily allow newsgroup */
  1997. X                    /*   with no unread news? */
  1998. X    bool retry;            /* cycle back to top of list? */
  1999. X    NG_NUM recent_ng = 0;
  2000. X    
  2001. X    current_ng = 0;
  2002. X    do {
  2003. X        retry = FALSE;
  2004. X        if (findlast) {
  2005. X        findlast = FALSE;
  2006. X        starthere = 0;
  2007. X        if (*lastngname) {
  2008. X            if ((ng = find_ng(lastngname)) == nextrcline)
  2009. X            ng = 0;
  2010. X            else {
  2011. X            set_ngname(lastngname);
  2012. X                set_toread(ng);
  2013. X            if (toread[ng] <= TR_NONE)
  2014. X                ng = 0;
  2015. X            }
  2016. X        }
  2017. X        }
  2018. X        else {
  2019. X        ng = starthere;
  2020. X        starthere = 0;
  2021. X        }
  2022. X        while (ng <= nextrcline) {    /* for each newsgroup */
  2023. X        mode = 'n';
  2024. X        if (ng >= nextrcline) {    /* after the last newsgroup? */
  2025. X            ng = nextrcline;    /* force it to 1 after */
  2026. X#ifdef ONLY
  2027. X            if (maxngtodo) {
  2028. X            if (retry)
  2029. X#ifdef VERBOSE
  2030. X                IF(verbose)
  2031. X                printf("\nRestriction %s%s still in effect.\n",
  2032. X                    ngtodo[0],
  2033. X                    maxngtodo > 1 ? ", etc." : nullstr) FLUSH;
  2034. X                ELSE
  2035. X#endif
  2036. X#ifdef TERSE
  2037. X                fputs("\n(\"Only\" mode.)\n",stdout) FLUSH;
  2038. X#endif
  2039. X            else {
  2040. X#ifdef VERBOSE
  2041. X                IF(verbose)
  2042. X                fputs("\nNo articles under restriction.",
  2043. X                  stdout) FLUSH;
  2044. X                ELSE
  2045. X#endif
  2046. X#ifdef TERSE
  2047. X                fputs("\nNo \"only\" articles.",stdout) FLUSH;
  2048. X#endif
  2049. X                end_only();    /* release the restriction */
  2050. X                retry = TRUE;
  2051. X            }
  2052. X            }
  2053. X#endif
  2054. X            dfltcmd = (retry ? "npq" : "qnp");
  2055. X#ifdef VERBOSE
  2056. X            IF(verbose)
  2057. X            sprintf(promptbuf,
  2058. X                "\n******** End of newsgroups--what next? [%s] ",
  2059. X                dfltcmd);
  2060. X            ELSE
  2061. X#endif
  2062. X#ifdef TERSE
  2063. X            sprintf(promptbuf,
  2064. X                "\n**** End--next? [%s] ", dfltcmd);
  2065. X#endif
  2066. X        }
  2067. X        else {
  2068. X            bool shoe_fits;    /* newsgroup matches restriction? */
  2069. X
  2070. X            if (toread[ng] >= TR_NONE) {    /* recalc toread? */
  2071. X            set_ngname(rcline[ng]);
  2072. X            if (shoe_fits = (special || inlist(ngname)))
  2073. X                set_toread(ng);
  2074. X            if (paranoid) {
  2075. X                recent_ng = current_ng;
  2076. X                current_ng = ng;
  2077. X                cleanup_rc();
  2078. X                    /* this may move newsgroups around */
  2079. X                ng = current_ng;
  2080. X                set_ngname(rcline[ng]);
  2081. X            }
  2082. X            }
  2083. X            if (toread[ng] < (maxngtodo||special ? TR_NONE : TR_ONE) || !shoe_fits) {
  2084. X                    /* unwanted newsgroup? */
  2085. X            ng++;        /* then skip it */
  2086. X            continue;
  2087. X            }
  2088. X    reprompt_newsgroup:
  2089. X#ifdef USETHREADS
  2090. X            dfltcmd = (ThreadedGroup && select_on
  2091. X            && (ART_NUM)toread[ng] >= select_on ? "+ynq" : "ynq");
  2092. X#else
  2093. X            dfltcmd = "ynq";
  2094. X#endif
  2095. X#ifdef VERBOSE
  2096. X            IF(verbose)
  2097. X            sprintf(promptbuf,
  2098. X                "\n******** %3ld unread article%s in %s--read now? [%s] ",
  2099. X                (long)toread[ng], (toread[ng]==TR_ONE ? nullstr : "s"),
  2100. X                ngname, dfltcmd);    /* format prompt string */
  2101. X            ELSE
  2102. X#endif
  2103. X#ifdef TERSE
  2104. X            sprintf(promptbuf,
  2105. X                "\n**** %3ld in %s--read? [%s] ",
  2106. X                (long)toread[ng],
  2107. X                ngname,dfltcmd);    /* format prompt string */
  2108. X#endif
  2109. X        }
  2110. X        special = FALSE;    /* go back to normal mode */
  2111. X        if (ng != current_ng) {
  2112. X            recent_ng = current_ng;
  2113. X                    /* remember previous newsgroup */
  2114. X            current_ng = ng;    /* remember current newsgroup */
  2115. X        }
  2116. X    reask_newsgroup:
  2117. X        unflush_output();    /* disable any ^O in effect */
  2118. X        fputs(promptbuf,stdout) FLUSH;/* print prompt */
  2119. X        fflush(stdout);
  2120. X    reinp_newsgroup:
  2121. X        eat_typeahead();
  2122. X        getcmd(buf);
  2123. X        if (errno || *buf == '\f') {
  2124. X            putchar('\n') FLUSH; /* if return from stop signal */
  2125. X            goto reask_newsgroup;    /* give them a prompt again */
  2126. X        }
  2127. X        setdef(buf,dfltcmd);
  2128. X#ifdef VERIFY
  2129. X        printcmd();
  2130. X#endif
  2131. X        switch (*buf) {
  2132. X        case 'p':        /* find previous unread newsgroup */
  2133. X            do {
  2134. X            if (ng <= 0)
  2135. X                break;
  2136. X            ng--;
  2137. X            if (toread[ng] == TR_NONE)
  2138. X                set_toread(ng);
  2139. X            } while (toread[ng] <= TR_NONE);
  2140. X            break;
  2141. X        case 'P':        /* goto previous newsgroup */
  2142. X            do {
  2143. X            if (ng <= 0)
  2144. X                break;
  2145. X            ng--;
  2146. X            } while (toread[ng] < TR_NONE);
  2147. X            special = TRUE;    /* don't skip it if toread==0 */
  2148. X            break;
  2149. X        case '-':
  2150. X            ng = recent_ng;    /* recall previous newsgroup */
  2151. X            special = TRUE;    /* don't skip it if toread==0 */
  2152. X            break;
  2153. X        case 'q': case 'Q': case 'x':    /* quit? */
  2154. X            oh_for_the_good_old_days = (*buf == 'x');
  2155. X            putchar('\n') FLUSH;
  2156. X            ng = nextrcline+1;    /* satisfy */
  2157. X            retry = FALSE;    /*   loop conditions */
  2158. X            break;
  2159. X        case '^':
  2160. X            putchar('\n') FLUSH;
  2161. X            ng = 0;
  2162. X            break;
  2163. X        case 'n':        /* find next unread newsgroup */
  2164. X            if (ng == nextrcline) {
  2165. X            putchar('\n') FLUSH;
  2166. X            retry = TRUE;
  2167. X            }
  2168. X            else if (toread[ng] > TR_NONE)
  2169. X            retry = TRUE;
  2170. X            ng++;
  2171. X            break;
  2172. X        case 'N':        /* goto next newsgroup */
  2173. X            ng++;
  2174. X            special = TRUE;    /* and don't skip it if toread==0 */
  2175. X            break;
  2176. X        case '1':        /* goto 1st newsgroup */
  2177. X            ng = 0;
  2178. X            special = TRUE;    /* and don't skip it if toread==0 */
  2179. X            break;
  2180. X        case '$':
  2181. X            ng = nextrcline;    /* goto last newsgroup */
  2182. X            retry = TRUE;
  2183. X            break;
  2184. X        case 'L':
  2185. X            list_newsgroups();
  2186. X            goto reask_newsgroup;
  2187. X        case '/': case '?':    /* scan for newsgroup pattern */
  2188. X#ifdef NGSEARCH
  2189. X            switch (ng_search(buf,TRUE)) {
  2190. X            case NGS_ABORT:
  2191. X            goto reinp_newsgroup;
  2192. X            case NGS_INTR:
  2193. X#ifdef VERBOSE
  2194. X            IF(verbose)
  2195. X                fputs("\n(Interrupted)\n",stdout) FLUSH;
  2196. X            ELSE
  2197. X#endif
  2198. X#ifdef TERSE
  2199. X                fputs("\n(Intr)\n",stdout) FLUSH;
  2200. X#endif
  2201. X            ng = current_ng;
  2202. X            goto reask_newsgroup;
  2203. X            case NGS_FOUND:
  2204. X            special = TRUE;    /* don't skip it if toread==0 */
  2205. X            break;
  2206. X            case NGS_NOTFOUND:
  2207. X#ifdef VERBOSE
  2208. X            IF(verbose)
  2209. X                fputs("\n\nNot found--use g to add newsgroups\n",
  2210. X                stdout) FLUSH;
  2211. X            ELSE
  2212. X#endif
  2213. X#ifdef TERSE
  2214. X                fputs("\n\nNot found\n",stdout) FLUSH;
  2215. X#endif
  2216. X            goto reask_newsgroup;
  2217. X            }
  2218. X#else
  2219. X            notincl("/");
  2220. X#endif
  2221. X            break;
  2222. X        case 'm':
  2223. X#ifndef RELOCATE
  2224. X            notincl("m");
  2225. X            break;
  2226. X#endif            
  2227. X        case 'g':    /* goto named newsgroup */
  2228. X            if (!finish_command(FALSE))
  2229. X                    /* if they didn't finish command */
  2230. X            goto reinp_newsgroup;    /* go try something else */
  2231. X            for (s = buf+1; *s == ' '; s++);
  2232. X                    /* skip leading spaces */
  2233. X            if (!*s)
  2234. X            strcpy(s,ngname);
  2235. X#ifdef RELOCATE
  2236. X            if (!get_ng(s,*buf=='m'))    /* try to find newsgroup */
  2237. X#else
  2238. X            if (!get_ng(s,FALSE))    /* try to find newsgroup */
  2239. X#endif
  2240. X            ng = current_ng;/* if not found, go nowhere */
  2241. X            special = TRUE;    /* don't skip it if toread==0 */
  2242. X            break;
  2243. X#ifdef DEBUGGING
  2244. X        case 'D':
  2245. X            printf("\nTries: %d Hits: %d\n",
  2246. X            softtries,softtries-softmisses) FLUSH;
  2247. X            goto reask_newsgroup;
  2248. X#endif
  2249. X        case '!':        /* shell escape */
  2250. X            if (escapade())     /* do command */
  2251. X            goto reinp_newsgroup;
  2252. X                    /* if rubbed out, re input */
  2253. X            goto reask_newsgroup;
  2254. X        case Ctl('k'):        /* edit global KILL file */
  2255. X            edit_kfile();
  2256. X            goto reask_newsgroup;
  2257. X        case 'c':        /* catch up */
  2258. X#ifdef CATCHUP
  2259. Xreask_catchup:
  2260. X#ifdef VERBOSE
  2261. X        IF(verbose)
  2262. X            in_char("\nDo you really want to mark everything as read? [yn] ", 'C');
  2263. X        ELSE
  2264. X#endif
  2265. X#ifdef TERSE
  2266. X            in_char("\nReally? [ynh] ", 'C');
  2267. X#endif
  2268. X            setdef(buf,"y");
  2269. X#ifdef VERIFY
  2270. X            printcmd();
  2271. X#endif
  2272. X            putchar('\n') FLUSH;
  2273. X            if (*buf == 'h') {
  2274. X#ifdef VERBOSE
  2275. X            printf("Type y or SP to mark all articles as read.\n");
  2276. X            printf("Type n to leave articles marked as they are.\n");
  2277. X#else
  2278. X            printf("y or SP to mark all read.\n");
  2279. X            printf("n to forget it.\n");
  2280. X#endif
  2281. X            goto reask_catchup;
  2282. X            }
  2283. X            else if (*buf!=' ' && *buf!='y' && *buf!='n' && *buf!='q') {
  2284. X            printf(hforhelp);
  2285. X            settle_down();
  2286. X            goto reask_catchup;
  2287. X            } else if ( (*buf == ' ' || *buf == 'y') && ng<nextrcline )
  2288. X            catch_up(ng);
  2289. X            else
  2290. X            retry = TRUE;
  2291. X            ng++;
  2292. X#else
  2293. X            notincl("c");
  2294. X#endif
  2295. X            break;
  2296. X        case 'u':        /* unsubscribe */
  2297. X            if (ng < nextrcline && toread[ng] >= TR_NONE) {
  2298. X                    /* unsubscribable? */
  2299. X            printf(unsubto,rcline[ng]) FLUSH;
  2300. X            rcchar[ng] = NEGCHAR;
  2301. X                    /* unsubscribe to (from?) it */
  2302. X            toread[ng] = TR_UNSUB;
  2303. X                    /* and make line invisible */
  2304. X            ng++;        /* do an automatic 'n' */
  2305. X            }
  2306. X            break;
  2307. X        case 'h': {        /* help */
  2308. X            int cmd;
  2309. X
  2310. X            if ((cmd = help_ng()) > 0)
  2311. X            pushchar(cmd);
  2312. X            goto reask_newsgroup;
  2313. X        }
  2314. X        case 'a':
  2315. X#ifndef FINDNEWNG
  2316. X            notincl("a");
  2317. X            goto reask_newsgroup;
  2318. X#else
  2319. X            /* FALL THROUGH */
  2320. X#endif
  2321. X        case 'o':
  2322. X#ifdef ONLY
  2323. X        {
  2324. X#ifdef FINDNEWNG
  2325. X            bool doscan = (*buf == 'a');
  2326. X#endif
  2327. X
  2328. X            if (!finish_command(TRUE)) /* get rest of command */
  2329. X            goto reinp_newsgroup;    /* if rubbed out, try something else */
  2330. X            end_only();
  2331. X            if (buf[1]) {
  2332. X            bool minusd = instr(buf+1,"-d") != Nullch;
  2333. X
  2334. X            sw_list(buf+1);
  2335. X            if (minusd)
  2336. X                cwd_check();
  2337. X            putchar('\n') FLUSH;
  2338. X#ifdef FINDNEWNG
  2339. X            if (doscan && maxngtodo)
  2340. X                scanactive();
  2341. X#endif
  2342. X            }
  2343. X            ng = 0;        /* simulate ^ */
  2344. X            retry = FALSE;
  2345. X            break;
  2346. X        }
  2347. X#else
  2348. X            notincl("o");
  2349. X            goto reask_newsgroup;
  2350. X#endif
  2351. X        case '&':
  2352. X            if (switcheroo()) /* get rest of command */
  2353. X            goto reinp_newsgroup;    /* if rubbed out, try something else */
  2354. X            goto reask_newsgroup;
  2355. X        case 'l': {        /* list other newsgroups */
  2356. X            if (!finish_command(TRUE)) /* get rest of command */
  2357. X            goto reinp_newsgroup;    /* if rubbed out, try something else */
  2358. X            for (s = buf+1; *s == ' '; s++);
  2359. X                        /* skip leading spaces */
  2360. X            sprintf(cmd_buf,"%s '%s'",filexp(NEWSGROUPS),s);
  2361. X            resetty();
  2362. X            if (doshell(sh,cmd_buf))
  2363. X#ifdef VERBOSE
  2364. X            IF(verbose)
  2365. X                fputs("    (Error from newsgroups program)\n",
  2366. X                stdout) FLUSH;
  2367. X            ELSE
  2368. X#endif
  2369. X#ifdef TERSE
  2370. X                fputs("(Error)\n",stdout) FLUSH;
  2371. X#endif
  2372. X            noecho();
  2373. X            crmode();
  2374. X            goto reask_newsgroup;
  2375. X        }
  2376. X#ifdef USETHREADS
  2377. X        case 'U': case '+':
  2378. X#endif
  2379. X        case '.': case '=':
  2380. X        case 'y': case 'Y': /* do normal thing */
  2381. X            if (ng >= nextrcline) {
  2382. X            fputs("\nNot on a newsgroup.",stdout) FLUSH;
  2383. X            goto reask_newsgroup;
  2384. X            }
  2385. X#ifdef USETHREADS
  2386. X            else if (*buf == '+' || *buf == 'U' || *buf == '=') {
  2387. X            buf[1] = '\0';
  2388. X            s = savestr(buf);
  2389. X            }
  2390. X#else
  2391. X            if (*buf == '=')
  2392. X            s = savestr("=");
  2393. X#endif
  2394. X            else if (*buf == '.') {    /* start command? */
  2395. X            if (!finish_command(FALSE)) /* get rest of command */
  2396. X                goto reinp_newsgroup;
  2397. X            s = savestr(buf+1);
  2398. X                    /* do_newsgroup will free it */
  2399. X            }
  2400. X            else
  2401. X            s = Nullch;
  2402. X            if (toread[ng])
  2403. X            retry = TRUE;
  2404. X            switch (do_newsgroup(s)) {
  2405. X            case NG_ERROR:
  2406. X            case NG_NORM:
  2407. X            ng++;
  2408. X            break;
  2409. X            case NG_ASK:
  2410. X            goto reprompt_newsgroup;
  2411. X            case NG_MINUS:
  2412. X            ng = recent_ng;    /* recall previous newsgroup */
  2413. X            special = TRUE;    /* don't skip it if toread==0 */
  2414. X            break;
  2415. X            }
  2416. X            break;
  2417. X#ifdef STRICTCR
  2418. X        case '\n':
  2419. X            fputs(badcr,stdout) FLUSH;
  2420. X            goto reask_newsgroup;
  2421. X#endif
  2422. X        case 'v':
  2423. X            printf("\n%s",rnid);
  2424. X            printf("\n%s",patchlevel);
  2425. X            printf("\nSend bugs to davison@borland.com\n") FLUSH;
  2426. X            goto reask_newsgroup;
  2427. X        default:
  2428. X            printf("\n%s",hforhelp) FLUSH;
  2429. X            settle_down();
  2430. X            goto reask_newsgroup;
  2431. X        }
  2432. X        }
  2433. X    } while (retry);
  2434. X    }
  2435. X
  2436. X    /* now write .newsrc back out */
  2437. X
  2438. X    write_rc();
  2439. X
  2440. X    if (oh_for_the_good_old_days)
  2441. X    get_old_rc();
  2442. X
  2443. X    finalize(0);            /* and exit */
  2444. X}
  2445. X
  2446. X/* set current newsgroup */
  2447. X
  2448. Xvoid
  2449. Xset_ngname(what)
  2450. Xchar *what;
  2451. X{
  2452. X    int len = strlen(what)+1;
  2453. X
  2454. X    growstr(&ngname,&ngnlen,len);
  2455. X    strcpy(ngname,what);
  2456. X    growstr(&ngdir,&ngdlen,len);
  2457. X    strcpy(ngdir,getngdir(ngname));
  2458. X}
  2459. X
  2460. Xstatic char *myngdir;
  2461. Xstatic int ngdirlen = 0;
  2462. X
  2463. Xchar *
  2464. Xgetngdir(ngnam)
  2465. Xchar *ngnam;
  2466. X{
  2467. X    register char *s;
  2468. X
  2469. X    growstr(&myngdir,&ngdirlen,strlen(ngnam)+1);
  2470. X    strcpy(myngdir,ngnam);
  2471. X    for (s = myngdir; *s; s++)
  2472. X    if (*s == '.')
  2473. X        *s = '/';
  2474. X    return myngdir;
  2475. X}
  2476. END_OF_FILE
  2477.   if test 14789 -ne `wc -c <'rn.c'`; then
  2478.     echo shar: \"'rn.c'\" unpacked with wrong size!
  2479.   fi
  2480.   # end of 'rn.c'
  2481. fi
  2482. echo shar: End of archive 9 \(of 14\).
  2483. cp /dev/null ark9isdone
  2484. MISSING=""
  2485. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ; do
  2486.     if test ! -f ark${I}isdone ; then
  2487.     MISSING="${MISSING} ${I}"
  2488.     fi
  2489. done
  2490. if test "${MISSING}" = "" ; then
  2491.     echo You have unpacked all 14 archives.
  2492.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2493. else
  2494.     echo You still must unpack the following archives:
  2495.     echo "        " ${MISSING}
  2496. fi
  2497. exit 0
  2498.